Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
等待Bash IO重定向中的子shell_Bash_Pipe_Wait_Pid_Subshell - Fatal编程技术网

等待Bash IO重定向中的子shell

等待Bash IO重定向中的子shell,bash,pipe,wait,pid,subshell,Bash,Pipe,Wait,Pid,Subshell,场景是,我需要我的主命令在当前shell中运行,这是必需的,或者会丢失所有环境内容,等等 所以,我不能就这样运行我的管道: #command-line 1 mainCommand | ( ...subshell commands... ) & #this wait works, but main command is in child process wait $! 我必须在当前shell中运行main命令: #command-line 2 mainCommand &&g

场景是,我需要我的主命令在当前shell中运行,这是必需的,或者会丢失所有环境内容,等等

所以,我不能就这样运行我的管道:

#command-line 1
mainCommand | (
  ...subshell commands...
) &

#this wait works, but main command is in child process
wait $!
我必须在当前shell中运行main命令:

#command-line 2
mainCommand &> >(
  ...subshell commands...
) &

#this wait is waiting for mainCommand, not subshell
wait $!
然而,在命令行2中,它只是一个命令,我不能将它发送到后台,只有子shell应该转到后台,然后我才能得到它的PID

如何让

  • 主命令必须在当前shell中
  • “wait”命令实际上是在等待子shell吗

我有锁定文件的解决方案,但我不喜欢使用文件,因为整个脚本会连续运行,反复编写/修改文件就像渗透文件系统。

较新版本的
bash
允许等待进程替换,但在此之前,我建议只使用命名管道

mkfifo p
( ... subshell commands ... ) < p &
mainCommand > p
wait
mkfifop
(…子shell命令…)p
等待

试试这个。您需要在subshell命令中添加一个
kill

sleep 100 &
export BACKGROUNDPID=$!

mainCommand &> >(
  ...subshell commands...
  kill "${BACKGROUNDPID}"
) &

wait ${BACKGROUNDPID}"

# execution continue here ...

您是否有理由相信
main命令将在子shell之后运行很长时间?一旦子shell退出,
main命令
将在尝试写入现已关闭的管道时立即退出。在
bash
5中,您将能够等待进程替换<代码>主命令>>(…);等待
会做你想做的。是的,期待已久的狂欢5@datdinhquoc增强版睡眠100?我不明白这会给你等待的时间设置100秒的限制。如果子shell命令在退出
sleep 100
后仍在运行,则脚本将继续运行。您可以使用更大的值
100
:其想法是,当子shell命令终止时,它仍应在后台运行。额外的
kill
将结束后台
sleep
过程,并解除
wait
tks的阻塞,我还在
/tmp
dir或
mount-tmpfs
我自己的目录中发现了一个类似的解决方案;当
mkfifo
/tmp
中创建一个文件时,情况类似,将命名管道放置在何处并不重要;它只是内存缓冲区的文件系统接口。实际上没有任何东西被写入磁盘。