摘要:我有一个bash脚本,它在后台运行一个进程,并且应该作为普通命令工作,并在命令替换块中运行,例如$(...)
。脚本本身会生成一个分支到后台的进程。它可以简化为这个测试用例:
#!/bin/sh
echo something
sleep 5 &
在shell中运行此脚本将立即返回(并打印“某些内容”),在$(...)
内运行它将挂起5秒钟,等待后台“睡眠”完成。
适用于在命令替换shell中启动的任何内容,并在后台生成进程,包括该进程树中的任何子进程。似乎影响bash和zsh,没有尝试过其他人。
原始问题:我有一个bash脚本,它应该将值打印到stdout,并在每次运行时将其复制到X剪贴板。
#!/bin/sh
echo something
echo something | xclip -selection clipboard
这个脚本(让我们称之为“某事”)用于获取这个词(实际上是另一个命令的输出)并以不同的方式使用,例如:
$ something
something
$ xclip -o -selection clipboard
something
$ echo $(something)
^C
打印到普通标准输出,将输出复制到剪贴板以在普通X应用程序中使用,并且还应该能够使用带有bash命令替换的标准输出,在任何命令的中间插入此单词。
然而,bash命令替换似乎迫使xclip
在前台保持活跃状态。 xclip
通常守护自己,因为X剪贴板要求客户端提供剪贴板内容,默认行为是在替换剪贴板内容后退出。
在xclip遇到这个问题后,我做了我在这个问题开头写的最小测试用例,所以它似乎适用于$(...)
shell中守护进程的任何东西
任何人都可以解释这种行为吗?有什么办法可以避免吗?
答案 0 :(得分:13)
如果希望后台进程不干扰命令替换,则必须断开其stdout。这将立即返回:
$ cat bg.sh
#!/bin/sh
echo before
sleep 5 >/dev/null &
echo after
$ date; x=$(./bg.sh); date; echo "$x"
Sat Jun 1 13:02:26 EDT 2013
Sat Jun 1 13:02:26 EDT 2013
before
after
您将无法捕获后台进程的标准输出,但如果您在后台运行它,则可能不关心。 bg.sh
进程始终可以写入磁盘。