Вызвать команду / скрипт, отключенный от управляющего терминала?


9

Я исследую поведение скрипта, который обычно запускается как автоматизированный процесс (например, cron, Jenkins). Сценарий может (в конце концов) вызывать команды, которые ведут себя по-разному (запрашивая ввод данных пользователем) при интерактивном запуске; например, patchспросит, что делать с обратным патчем, и svnпопросит пароли, но мне нужно посмотреть, что происходит, когда они запускаются неинтерактивно.

Убедить, patchчто это неинтерактивно, довольно легко; Мне просто нужно перенаправить, stdoutчтобы быть не-tty:

$ </dev/null > >(cat) /path/to/myscript --args

Однако svnподключится к управляющему терминалу, если он существует; редактирование сценариев, которые нужно передать, на --non-interactiveсамом деле не вариант, так как это происходит на нескольких уровнях, и было бы трудно быть уверенным, что я нашел каждый вызов.

Есть ли способ вызвать скрипт / команду неинтерактивно, без управляющего терминала (так, чтобы /dev/ttyон не существовал)? Я бы предпочел, чтобы stdout / stderr продолжал идти в мой терминал.

(Я нашел вопрос « Выполнять сценарий в неинтерактивной оболочке», но ответы на него обсуждают различия между cron и пользовательской средой; я уже устранил все различия, кроме неинтерактивности.)

Ответы:


13

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

$ setsid sh -c 'tty; ps -jp "$$"; echo test' < /dev/null > log 2>&1
$ cat log
not a tty
  PID  PGID   SID TTY          TIME CMD
19506 19506 19506 ?        00:00:00 sh
test

Смотрите также start-stop-daemonкоманду, найденную в некоторых дистрибутивах Linux. Там также daemonкоманда.


Что означает этот вывод? Выглядит очень загадочно.
анатолий техтоник

2
@anatolytechtonik важными частями являются "не tty", что является выводом ttyподтверждения, что на stdin нет терминала, и "?" в столбце psвывода TTY, который подтверждает, что tty для shпроцесса не контролируется (и все, что выполняется под ним).
mr.spuratic

Чтобы запустить команду как любую другую команду, используйте setsid -w. Пример: setsid -w sh -c 'tty < /dev/tty'дает sh: 1: cannot open /dev/tty: No such device or address(Примечание: /dev/ttyваш контрольный tty). Без -wsetsid запускает процесс параллельно / в фоновом режиме.
Тино

0

Возможно, вы захотите сделать сценарий ожидания. Пример с SVN:

/programming/609445/using-expect-to-login-into-svn


Это не работает; ожидайте запуска команд в интерактивном режиме.
Ecatmur

В каком смысле интерактивно? В том смысле, что это требует ввода от пользователя? Если это то, что вы имеете в виду, в этом случае не будет особого смысла. Один из примеров, для которого я его использую, - в Solaris команда passwd не имеет опции --stdin, поэтому у меня настроен cronjob, который выполняет сценарий ожидающего выполнения, который оборачивает passwd, чтобы передать ему случайный пароль для учетной записи. Взаимодействие с человеком не требуется. Насколько я понимаю, это требование пользователя. Я мог бы неправильно понять, хотя.
Братчли

На самом деле, чем больше я перечитываю это, тем больше понимаю, что неправильно поняла, к чему вы стремились. Извиняюсь.
Братчли

0

Иногда вам нужно держать stdin открытым (не получать eof на stdin) (например, ожидать). В этом случае измените / dev / null на / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.