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

25

Вместо того, чтобы перефразировать мой вопрос, позвольте мне описать вам желаемый пользовательский случай:

Я создаю короткий shell-скрипт для запуска команды "gnome-терминал --someoptionflagname" мой текст для публикации "и запускаю этот скрипт.

Появляется Gnome-терминал с подсказкой командной строки, за которой следует мой текст.

то есть: fields@mycomputer:/$ my text to be posted

Можно ли это сделать?

э.д.с.
источник
Если эта ошибка когда-либо исправлена ​​в Ubuntu, вам стоит заглянуть в cnee .
rndrü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
ændrük
источник
+1 за использование Expect. Я использовал это в течение многих лет, чтобы помочь автоматизировать многие вещи.
Марко Чеппи
Это здорово. Я надеялся, что будет какой-то простой (ish) ответ, основанный на функциональности gnome-терминала по умолчанию, но похоже, что это отвечает работе.
EMF
Этот долго мучил меня, я почти не мог вспомнить, каков был предполагаемый вариант использования. Итак, для пояснения: я бы хотел сделать что-то вроде "gnome-terminal -e ls", но проблема в том, чтобы окно оставалось открытым. Таким образом, в основном это ярлыки для открытия терминала и запуска команд оболочки. Это проясняет вопросы против ответов aendruk / msw?
EMF
1
Если все, что вам нужно, это чтобы терминал оставался открытым после команды, есть гораздо более простые решения .
rndrü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

Предложение Эндрюка очень хорошее и сработало для меня, однако команда жестко запрограммирована в скрипте, и если вы измените размер окна терминала, он не будет работать хорошо. Используя его код в качестве основы, я добавил возможность посылать сценарию 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

Ответ Ундрюка хорош, но, возможно, немного тяжел для этой задачи.

Вот скрипт, который пишет скрипт на основе своих аргументов

#!/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-терминал должен запустить мини-скрипт и запустить интерактивную оболочку. Когда gnome-терминал завершает работу, временный сценарий удаляется, потому что мусор не охлаждается.

Последняя строка не является частью мини-скрипта, она показывает, что мини-скрипт работает. Если приведенный выше 11-строчный скрипт находится в файле с именем, rt.shто chmodон делает его исполняемым, а затем выполняется.

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

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

hello world

в первой строке, а затем запускает интерактивную оболочку:

msw@myhost:~$
MSW
источник
Я думаю, что ваш сценарий может быть сокращен до gnome-terminal -x sh -c "echo hello world; bash", что я не думаю, что вопрос задает.
rndrük
Это выглядит круто. Можете ли вы объяснить, что здесь происходит?
EMF
1
Эмфилдс: Я аннотировал это для тебя.
2010 г.
1
ты жжешь. спасибо за аннотации, такая помощь делает барьер для входа в сценарии намного более доступным
emf
0

Два ответа, которые мне больше всего понравились для решения этой проблемы, это использование, expectи этот, где они рекомендуют использовать --init-fileфлаг либо в shebang, либо при выполнении терминала:

#!/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 Возможно, это лучшее решение (по причинам, которые я обрисую), за исключением того, что я не могу контролировать, установлено ли оно в моей целевой среде.

Проблемы я столкнулся с Баш - х --init-fileи gnome-terminal«S , --commandкак взломать , чтобы решить это оболочка не имеет доступ к STDIN при выполнении скриптов инициализации. Если, например, я хочу запустить что-то, что потребует ввода данных пользователем (ftp, telnet и т. Д.), Но потом оставить родительскую оболочку включенной, это не сработает; единственное исключение, которое я видел до сих пор, это ssh:

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

... но то, что мне нужно, сложнее, чем этот игрушечный пример. В любом случае, я надеюсь, что --init-fileматериал будет полезен всем, кто читает этот вопрос.

Брайан Ванденберг
источник
-1

Вы можете использовать аргументы -eили -xдля запуска команды внутри недавно запущенного терминала, но это не совсем то, что вам нужно.

Карл Билефельдт
источник
близко, но не совсем то, что я ищу. В этом случае одной из проблем является то, что после выполнения и завершения терминал немедленно закрывается. Итак, допустим, я хочу ярлык «ls ~ / notes», он закроется, прежде чем я смогу просмотреть вывод.
EMF
Если бы было решение для этого, это решило бы большинство случаев, которые я ищу.
EMF