在包含重定向的指令中,无论是1
还是2
或什么都没有,在 的左侧>/dev/null
丢弃输出,在本例中是[24] 1073640
。 这与我的预期相反,我可能误解了什么? 又代表什么[24]
?
$ uname -r
6.7.3-arch1-2
$ PIPE=$(mktemp -u)
$ mkfifo "$PIPE"
$ python > "$PIPE" 1>/dev/null & # EXPECTED: no output
[24] 1073640
$ python_id=$!
$ printf "python_id=%s\n" "$python_id"
python_id=1073640
https://www.gnu.org/software/bash/manual/html_node/Lists.html:
如果命令以控制运算符“&”终止,则 shell 会在子 shell 中异步执行该命令。
https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html:
($!) 扩展为最近放入后台的作业的进程 ID,
答案1
不是[24] 1073640
程序的输出;它是由 shell 输出的,表示它正在跟踪后台作业。在这种情况下,24
是 shell 分配的内部作业 ID(只是一种方便的快捷方式),而1073640
是真正的进程 ID。
交互式 shell 通常会跟踪所有后台作业,以便您可以恢复它们,并且 shell 可以在作业完成时通知您;例如,运行jobs
将列出该 shell 中的所有作业,而fg 24
快捷方式%24
会将作业带到前台。
(这在 shell 脚本中不会发生。)
如果您想取消跟踪已经跟踪的作业,disown
那么;如果您想防止命令被跟踪为作业,1)考虑是否应该将其作为服务启动,2)如果不是,则在子 shell 中运行它(foo &)
;3)再次考虑它是否应该作为服务。
(foo&)
之所以有效,是因为(..)
将产生一个新的 shell 进程,而该进程无法将作业信息传送到主进程。另一个选项是setsid foo
出于不同的原因而有效。
您的命令可能应该有2>
而不是1>
,因为文件描述符#1已经是>
默认操作的(这意味着您的命令冗余地重定向了 stdout 两次,但对 stderr 不执行任何操作)。