我正在研究通常作为自动化进程运行的脚本的行为(例如 cron、Jenkins)。交互运行时,脚本(最终)可以调用行为不同的命令(寻求用户输入);例如,patch
会询问如何处理反向补丁,并svn
会询问密码,但我需要看看它们以非交互方式运行时会发生什么。
说服patch
它是非交互式的相当容易;我只需要重定向stdout
为非 tty:
$ </dev/null > >(cat) /path/to/myscript --args
但是svn
将连接到控制终端(如果存在);编辑脚本以通过--non-interactive
并不是真正的选择,因为这是来自多个层次的深度,并且很难确定我是否找到了每个调用。
有没有一种方法可以在没有控制终端的情况下以非交互方式调用脚本/命令(因此/dev/tty
不存在)?我更喜欢 stdout/stderr 仍然转到我的终端。
(我发现这个问题在非交互式 shell 中运行脚本?但答案讨论了 cron 和用户环境之间的差异;我已经消除了除非交互性之外的所有差异。)
答案1
您需要启动另一个未附加到终端的会话,例如:
$ 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
您可能想要执行一个期望脚本。 SVN 示例:
https://stackoverflow.com/questions/609445/using-expect-to-login-into-svn
答案3
有时您需要保持标准输入打开(不在标准输入上接收 eof)(例如期望)。在这种情况下,将 /dev/null 更改为 /dev/zero。
setsid sh -c 'make test' </dev/zero >log 2>&1