Як запустити термінал з певним текстом, який вже вводиться в командному рядку?


25

Замість того, щоб перефразовувати моє запитання, дозвольте мені описати вам бажаний випадок користувача:

Я створюю короткий скрипт оболонки для запуску команди "gnome-terminal --someoptionflagname" мій текст для публікації "", і виконую цей сценарій.

Вискакує термін Gnome, із командним рядком та моїм текстом.

тобто: fields@mycomputer:/$ my text to be posted

Чи можна це зробити?


Якщо ця помилка коли-небудь виправлена ​​в Ubuntu, ви повинні вивчити cnee .
ændrük

@ ændrük Це виправлено, і назва пакета xneeзараз.
десерт

Відповіді:


32

Це можна зробити за допомогою очікування ( встановлення ). Створіть і зробіть виконуваним ~/bin/myprompt:

#!/usr/bin/expect -f

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send "my text to be posted"

# Hand over control to the user
interact

exit

і запустити термінал Gnome за допомогою:

gnome-terminal -e ~/bin/myprompt

+1 за використання Expect. Я використовую це протягом багатьох років, щоб допомогти автоматизувати багато речей.
Марко Чеппі

Це круто. Я сподівався, що буде якийсь простий (ish) відповідь, заснований на функціональності гнома-терміналу за замовчуванням, але схоже, що це відповідає на роботу.
emf

Цей клопіт мене так довго, я майже не міг пригадати, що це за призначенням. Отже, для уточнення: я хотів би зробити щось на кшталт "gnome-terminal -e ls", але суть полягає в тому, щоб вікно залишалося відкритим. Отже, в основному клавіші швидкого доступу до відкриття терміналу та запуску команд оболонки. Чи пояснює це питання проти відповідей aendruk / msw?
emf

1
Якщо все, що ви хочете, щоб термінал залишався відкритим після команди, є набагато простіші рішення .
ændrük

Супер, дякую. Я успішно інтегрував це в сценарій оболонки, який викликає інструмент інтеграції даних Pentaho. Потім я додав виклик цього сценарію до запуску Unity в 11.10, і він працює як шарм.
bioShark

8

Якщо я правильно розумію, ви хочете, щоб ваш перший рядок вводу був попередньо заповнений вмістом, який ви передаєте в командному рядку gnome-terminal.

Я не знаю, як саме це зробити з bash, але ось щось наближається. У ваших ~/.bashrc, додайте наступний рядок в самому кінці:

history -s "$BASH_INITIAL_COMMAND"

Запустіть gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bashі натисніть Upпідказку, щоб згадати текст.

Зауважте також, що якщо ви set -o historyпомітите коментарі в кінці ваших записів .bashrc, вони будуть введені в історію, коли починається bash, тому ви можете використовувати їх як основу для редагування, дотягнувшись до них Upключа та видаливши початковий #.


2
Хоча це не зовсім рішення, яке я шукав, це цікаво саме по собі.
emf

8

Пропозиція ændrük дуже хороша і працює для мене, проте команда жорстко кодується в сценарії, і якщо ви зміните розмір вікна терміналу, він не працює добре. Використовуючи його код як базовий, я додав можливість надсилати команду myprompt як аргумент, і цей скрипт правильно обробляє розмір вікна терміналу.

#!/usr/bin/expect

#trap sigwinch and pass it to the child we spawned
#this allows the gnome-terminal window to be resized
trap {
 set rows [stty rows]
 set cols [stty columns]
 stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH

set arg1 [lindex $argv 0]

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send $arg1

# Hand over control to the user
interact

exit

і запустити термінал Gnome за допомогою:

gnome-terminal -e "~/bin/myprompt \"my text to be posted\""

1

Відповідь ændrük чудова, але, можливо, трохи важка для виконання завдання.

Ось сценарій, який пише сценарій на основі своїх аргументів

#!/bin/sh
# terminal-plus-command: start a subordinate terminal which runs
# the interactive shell after first running the command arguments

tmpscript=/tmp/tmpscript.$$
echo "#!$SHELL" > $tmpscript
echo "$@" >> $tmpscript
echo exec "$SHELL" >> $tmpscript
chmod +x $tmpscript
gnome-terminal --command $tmpscript
rm -f $tmpscript

Якщо ви не багато займалися програмуванням оболонок, тут, мабуть, є більше магії, ніж є. По-перше, я називаю тимчасовий файл для зберігання скрипту, де $$є ідентифікатор процесу оболонки, на якій працює цей скрипт. /tmp/something.$$Метафора використовується в разі , якщо два примірника цього скрипта запускається в той же час, вони не будуть намагатися використовувати один і той же тимчасовий файл.

Змінна $SHELLвстановлюється на ім'я оболонки, на якій працює сценарій. Якщо ви використовуєте / usr / bin / bash, імовірно, ви хочете, щоб міні-скрипт також використовував його.

"$@"Це оболонка ідіома «інтерполювати всі мої аргументи, цитуючи їх , якщо це необхідно». Цей своєрідний синтаксис викликає

script.sh 'my file' your\ file

інтерполювати аргументи як два елементи

"my file" "your file"

замість чотирьох, які $@дадуть урожай

"my" "file" "your" "file"

Останні рядки сценарію впорядковують, щоб gnome-термінал почав запускати міні-скрипт, а потім запустити інтерактивну оболонку. Коли гном-термінал виходить, тимчасовий сценарій видаляється, оскільки засмічення не охолоджене.

Останній рядок не є частиною міні-скрипту, він демонструє, що міні-скрипт працює. Якщо сценарій 11 рядків вище знаходиться у файлі, який називається, rt.shто chmodробить його виконуваним і тоді він виконується.

$ chmod +x rt.sh && ./rt.sh echo hello world

Результатом усього цього стане термінал гнома, який запускається, відображається

hello world

на першому рядку, а потім починає інтерактивну оболонку:

msw@myhost:~$

Я думаю, що ваш сценарій може бути зведений до gnome-terminal -x sh -c "echo hello world; bash", чого я не думаю, що це питання.
ændrük

Це виглядає круто. Чи можете ви пояснити, що тут відбувається?
emf

1
emfields: Я це помітив для вас.
msw

1
ти рок. спасибі за анотації, ця допомога робить перешкоду для входу зі сценаріями набагато доступнішою
emf

0

Два відповіді, які мені найбільше сподобалися для вирішення цього питання, використовуються, expectі цей, де вони рекомендують використовувати --init-fileпрапор або в шебанге, або під час виконання терміналу:

#!/bin/bash --init-file
commands to run

... і виконати його як:

xterm -e /path/to/script
# or
gnome-terminal -e /path/to/script
# or
the-terminal -e bash --init-file /path/to/script/with/no/shebang

expect це, мабуть, краще рішення (з причин, які я викладу), за винятком того, що я не можу контролювати, чи встановлено він у моєму цільовому середовищі.

Проблема, з якою я зіткнувся з bash's --init-fileі gnome-terminals --commandяк хак для вирішення цього питання, - оболонка не має доступу до STDIN під час виконання init-скриптів. Наприклад, якщо я хочу запустити щось, що потребує введення користувача (ftp, telnet тощо), але залишити батьківську оболонку після цього вона не працюватиме; єдиний виняток, який я бачив до цього часу, - ssh:

xterm -e /bin/bash --init-file <(echo 'ssh -X some-machine')

... але те, що мені потрібно, складніше, ніж цей приклад іграшки. У будь-якому випадку, я сподіваюся, що цей --init-fileматеріал буде корисним для всіх, хто читає це запитання.


-1

Ви можете використовувати аргументи -eабо -xдля запуску команди всередині щойно спливаючого терміналу, але це не зовсім те, що ви хочете.


близько, але не зовсім те, що я шукаю. Одна з проблем у цьому випадку полягає в тому, що після виконання та завершення термінал негайно закриється. Отже, скажімо, я хочу ярлик до "ls ~ / notes", він закриється, перш ніж я можу переглянути вихід.
emf

Якби для цього було рішення, воно вирішило б більшість випадків, які я шукаю.
emf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.