Вывод команды канала к входу команды running/backgrounded

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

Если Вы хотите выполнить его на удаленной машине, посмотрите на ~/.bash_logout, который выполняется, когда оболочка входа в систему выходит из системы корректно. От man bash:

Когда оболочка входа в систему выходит, удар читает и выполняет команды из файла ~/.bash_logout, если это существует.

Можно выполнить в тесте ~/.bash_logout чтобы проверить, является ли вышедшая оболочка сессией SSH, что-то как следующее должно работать:

if [[ $SSH_CLIENT || $SSH_CONNECTION || $SSH_TTY ]]; then
    # commands go here
fi

Если Вы хотите выполнить его на локальной машине, создайте функциональную обертку вокруг ssh. Что-то как следующее должно работать:

ssh() {
    if command ssh "$@"; then
        # commands go here
    fi
}

Это может быть слишком просто для Ваших потребностей, но Вы получаете идею.

4
18.07.2013, 21:24
3 ответа

После того как Вы запускаете:

rm -i -- * &

rm был запущен с любого stdin, был в Вашей оболочке в то время, когда Вы вызвали ту команду.

Если это был терминал, то rm будет обычно приостанавливаться (с сигналом SIGTTIN), как только он пытался читать из него (так как это не находится в группе приоритетного процесса терминала).

Если Вы хотите, чтобы это читало из чего-то еще, необходимо сказать этому вновь открыть свой дескриптор файла 0 на чем-то еще.

Вы могли сделать это с отладчиком (здесь предполагающий, что Вы находитесь на Linux):

rm_pid=$!
coproc yes
gdb --pid="$rm_pid" --batch \
    -ex "call close(0)" \
    -ex "call open(\"/proc/$$/fd/$COPROC\", 0)" /bin/rm
kill -s CONT "$rm_pid"

Выше, мы запускаем yes в фоне с его stdin и stdout, перенаправленным к каналу. Другой конец того канала находится в оболочке (процесс $$) на дескрипторе файла ${COPROC[0]} иначе $COPROC.

Затем с gdb, мы говорим rm закрыть его fd 0 и вновь открыть его на том же самом канале.

3
27.01.2020, 20:49
  • 1
    Это - некоторое истинное колдовство. –  Snowball 27.09.2014, 08:36
  • 2
    После долгого времени я переключился на этот невероятный ответ, потому что Ваш далеко превосходил ранее выбранный. Спасибо Stephane, у Вас всегда есть удивительные ответы. –  Gregg Leventhal 21.04.2016, 19:59

Да, но Вам нужен немного больше.

При отправке программы в фон, Вы отсоединяете его от stdin связанный с Вашим терминалом. Необходимо запустить его вместо этого с альтернативным входом, в этом случае канал.

$ mkfifo alternate_input
$ command_that_expects_input < alternate_input

Вы теперь присвоили файл канала (alternate_input) как stdin для процесса command_that_expects_input. Для отправки входа просто поместите что-то в канал.

$ echo foo > alternate_input

В этом случае строка foo становится передается stdin для command_that_expects_input.

5
27.01.2020, 20:49
  • 1
    Превосходный, это - хорошее решение. –  Gregg Leventhal 24.07.2013, 00:17
  • 2
    @gleventhal: если это лучше отвечает на Ваш вопрос, необходимо выбрать его для потомства. –  bahamat 25.07.2013, 11:54
  • 3
    Сделанный. Одна вещь, отсутствующая в Вашем ответе, состоит точно в том, как я должен устроиться на работу происхождения и выполнить перенаправление на нем. Следите за определением, как сделать так? –  Gregg Leventhal 25.07.2013, 21:05
  • 4
    Необходимо сделать перенаправление, прежде чем оно перейдет к фону, или можно программировать его для открытия предопределенного stdin. –  bahamat 26.07.2013, 00:10
  • 5
    Точка вопроса была то, как сделать это задним числом все же. –  Gregg Leventhal 26.07.2013, 18:42

Путем Вы постулируете, нет. Как terdon говорит, намного легче, если Вы знаете, что необходимо передать вход по каналу во-первых. В редком (настолько редкий я никогда не встречался с ним) случай, где программа не ожидает входа теперь, но будет ожидать вход в будущем, можно настроить именованный канал как вход к тому процессу, фон это, затем отправить вывод позже запущенного процесса к тому же именованному каналу, но необходимо настроить именованный канал заранее.

1
27.01.2020, 20:49
  • 1
    Спасибо. Я больше думал о ситуации, где Вы устанавливаете флаг для запроса или забыли устанавливать флаг, чтобы не запросить (т.е. комната-i или конфетка без-y) и требуемый задним числом изменять это. –  Gregg Leventhal 18.07.2013, 21:56
  • 2
    Нет никакого способа сделать это. Скорее единственные хотят сделать, который должен уничтожить и перезапустить процесс с флагом, который Вы означали устанавливать. –  John 18.07.2013, 22:00

Теги

Похожие вопросы