预期的目的是:
下载一个 shell 文件并在后台执行,以避免长时间等待.
我的做法如下:
wget -O - http://a.com/b.sh|bash
不过这里并未转入后台执行,我只知道单条命令在命令末端追加 & 符号即可。可看起来这并不适用于 pipe.
请教大家正确的写法是?
nohup wget -O - http://a.com/b.sh|bash 或运行 wget -O - http://a.com/b.sh|bash 后按 ctrl + z 再输入 bg 回车
bg - run jobs in the background
#7 楼 @blacktulip
我执行的命令是这样的
wget -O - http://a.com/b.sh | bash - &
运行后并没有获得输入焦点,按任意键才会跳转到输入...
#8 楼 @hellomac 不是没焦点,是输出占用了 STDOUT,都重定向一下
wget -O - -o log http://a.com/b.sh | bash - &> b.log &
如果只是暂时将进程放到后台,可以用 & 或 bg 等 shell 的作业控制命令即可,如果是一个需要长期在后台 run 的守护进程,建议程序遵循 daemon 编程规则,最要不要用 nohup,用不好会碰到各种问题
我这么说的原因是,当一个进程在后台运行,启动它的会话已经关闭时,那么它的标准 IO 所指向的文件 v 节点已经关闭,当进程试图向标准 IO 写入数据时,它会得到一个 IO 异常,如果程序没有处理该异常,那么进程就会异常终止。nohup 虽然重定向了进程的标准 IO,但是这个是有条件的:只有当标准 IO 指向的是一个 tty 时,它才会这么做,有一个很常见的反例:
for host in ...; do
ssh -o StrictHostKeyChecking username@$host 'nohup cmd &'
done
通过上述命令批量在远程机器上启动后台程序,此时标准 IO 指向的不是 tty,而是一个 socket,nohup 不会重定向 cmd 的标准 IO,上面的脚本实际上很可能就卡在第一次循环就停住了。
再者有的人其实不理解 shell 是如何解析一个输入行的,当你敲下 nohup cmd1 | cmd2 & 这样的命令的时候,它运行的结果可能和你期望的是不一样的