Отправить код ключа в программу командной строки на OS X - PullRequest
2 голосов
/ 11 апреля 2010

Я хочу сделать скрипт, который запускает программу, а затем отправляет ей ключ ввода. В псевдо-скрипте:

#!/bin/bash
./program << (PRESS CONTROL-Z)

Программа работает, поэтому, если в скрипте были дополнительные команды, они не будут доступны, если, скажем, control-z не завершит программу.

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

Ответы [ 4 ]

2 голосов
/ 14 сентября 2010

Я думаю, что это, вероятно, лучшее решение, чем «ожидаемо», поскольку оно может быть выполнено в собственном скрипте bash, мне будет интересно посмотреть, что вы думаете.

Использование

`printf "character code here"` 

обратите внимание на галочки

Так, например, я написал скрипт, который управляет сеансом экрана удаленного GNU, следующая строка открывает окно 2 и выдает комбинацию клавиш ctrl-c

ssh -t user@$host screen -p 2 -X stuff `printf "\003"`
  • Опция -t имитирует ввод с терминала на удаленном компьютере.
  • -p позволяет нам указать имя или номер окна, к которому мы подключаемся в сеансе экрана.
  • \ 003это bash формат символьного кода 0x03

См. здесь для полной ссылки на коды.

Чтобы найти код некоторого клавишного ввода, вы можете использовать

printf "%#x\n" "'X"
0x58
  • Если X - это ключ, вы хотите найти код
  • Чтобы найти коды не-литералов, вы можете использовать ctrl-v (заставляет bash добавлять следующий ключ ккомандной строки, а не интерпретировать его), а затем введите ключ сombo, поэтому, если бы я хотел найти код клавиши для ctrl-c, я бы удалил X, нажмите ctrl-v, а затем нажмите ctrl-c.

И последнее, что упоминается в приведенной выше ссылке на код ascii.0x13 как возврат каретки, но в руководстве на экране они указывают 0x15 как код ввода, кто-нибудь знает почему?Я проверил на локальном экране, и когда я нажимаю, ввод 0x13 производится, но при отправке команд через ssh на удаленный экран 0x13 не работает, а 0x15 работает.

Надеюсь, что помогает

Пирс

1 голос
/ 11 апреля 2010

Возможно, вы ищете expect (из http://expect.nist.gov/).). Это связано со сложностями псевдо-tty, которые заставляют программу показывать, что она вводится из сценария (в этом сценарии expect программа) приходит с терминала.

В качестве альтернативы вы можете использовать echo или cat и направить вывод этого в программу - это зависит от программы.

0 голосов
/ 11 апреля 2010

Если вы хотите создать фоновую программу, используйте:

./program &    # The & sends the command to the background
echo commands here are executed while program is in the background
…
wait           # Wait for the completion of background commands
echo commands here are executed after background program has completed

Редактировать: Если вы намереваетесь остановить программу (как это часто делает ctrl-Z в * nix оболочках), вы можете отправить ему сигнал STOP:

kill -STOP pid

Чтобы возобновить выполнение, отправьте ему сигнал CONT:

kill -CONT pid

В каждом из этих примеров pid - это идентификатор процесса программы. Если вы запустите его в скрипте, его легко получить с помощью переменной $!, например,

./prog &
echo prog started in the background
pid_of_prog=$!
kill -STOP $pid_of_prog
echo prog stopped
kill -CONT $pid_of_prog
echo prog continues
wait
echo prog finished

Редактировать 2: Если ваша программа завершает работу при получении символа ctrl-Z, помните, что управляющие символы имеют числовое значение буквы позиции в алфавите (т.е. Ctrl-A 1, Ctrl-B 2 и т. д.). Чтобы отправить этого персонажа в программу, вы можете:

echo -e "\032" | ./prog

(032 - это 26, то есть ^ Z, в восьмеричном виде. Конечно, вы можете создать тот же символ любым способом, возможно, добавив его в конец другого ввода, например ( cat inputfile ; echo -e "\032" ) | ./prog.

Но это не обязательно работает; программа должна быть спроектирована так, чтобы распознавать этот символ из входных данных (что, вероятно, не будет); обычно оболочка ловит его. С другой стороны, большинство программ, считывающих ввод с stdin, просто завершают работу, когда ввод заканчивается, поэтому перенаправление любого конечного ввода (даже </dev/null) должно привести к его завершению.

И, наконец, если целью было остановить выполнение программы, когда произошло какое-то другое событие (обнаруженное в другом месте скрипта), вы можете просто kill it…

0 голосов
/ 11 апреля 2010

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

#!/bin/bash
./program&
...