Викликати команду / скрипт, відключений від керуючого терміналу?


9

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

Переконати, patchщо це неінтерактивна, досить легко; Мені просто потрібно переспрямувати, stdoutщоб бути нетиповим:

$ </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команда.


Що означає цей вихід? Виглядає дуже крикливо.
anatoly techtonik

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). Без -wsetid запускається процес паралельно / фону.
Тіно

0

Ви, ймовірно, захочете зробити сценарій очікування. Приклад зі SVN:

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


Це не працює; очікуйте, що команди виконуються інтерактивно.
екатмур

Інтерактивно в якому сенсі? У тому сенсі, що він вимагає введення від користувача? Якщо це ви маєте на увазі, не було б великого сенсу очікувати, що існує в такому випадку. Одним із прикладів, для якого я користуюся, є 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.