【问题标题】:Wait for the subshell in Bash IO redirection等待 Bash IO 重定向中的 subshel​​l
【发布时间】:2018-10-05 10:54:31
【问题描述】:

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

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

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

#this wait works, but main command is in child process
wait $!

我必须在当前 shell 中运行主命令:

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

#this wait is waiting for mainCommand, not subshell
wait $!

但是,在命令行 2 中,它只是一个命令,我不能将其发送到后台,只有 subshel​​l 应该进入后台,然后我才能获取它的 PID。

如何让

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

我有锁定文件的解决方案,但我不喜欢使用文件,因为整个脚本不断运行,一次又一次地写入/修改文件就像穿透文件系统。

【问题讨论】:

  • 你有理由相信mainCommand 会在子shell之后运行很长时间吗?一旦 subshel​​l 退出,mainCommand 将在尝试写入现已关闭的管道时立即退出。
  • bash 5,您将可以等待进程替换; mainCommand > >(...); wait 会做你想做的事。
  • 是的,期待已久的 bash 5

标签: bash pipe wait pid subshell


【解决方案1】:

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

mkfifo p
( ... subshell commands ... ) < p &
mainCommand > p
wait

【讨论】:

  • tks,我还在/tmp 目录或mount -t tmpfs 我自己的目录中找到了使用RAM 文件的类似解决方案;当mkfifo/tmp 中创建文件时类似
  • 把命名管道放在哪里并不重要;它只是内存缓冲区的文件系统接口。实际上没有任何东西写入磁盘。
【解决方案2】:

试试这个。您需要在子shell 命令中添加kill

sleep 100 &
export BACKGROUNDPID=$!

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

wait ${BACKGROUNDPID}"

# execution continue here ...

【讨论】:

  • @datdinhquoc 增强版
  • 睡眠 100?我不明白
  • 这对您将等待多长时间设置了 100 秒的时间限制。如果sleep 100 退出后 subshel​​l 命令仍在运行,则脚本将继续运行。
  • 您可以使用比100 更大的值:想法是当子shell 命令终止时它仍应在后台运行。额外的kill将结束后台sleep进程,并解除对wait的阻塞
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多