我试图在后台保存每个并行运行并在不同时间结束的进程的返回值。
例如(这里的返回值在所有进程中都是0,但在我的脚本中会有很多返回值):
#!/bin/bash
echo "" > empty.txt
(sleep 4 ; echo "my return value is $? " >> empty.txt ) &
(sleep 3 ; echo "my return value is $? " >> empty.txt ) &
(sleep 12 ; echo "my return value is $? " >> empty.txt ) &
(sleep 9 ; echo "my return value is $? " >> empty.txt ) &
(sleep 7 ; echo "my return value is $? " >> empty.txt ) &
(sleep 6 ; echo "my return value is $? " >> empty.txt ) &
(sleep 4 ; echo "my return value is $? " >> empty.txt ) &
但是这里我不知道每个进程的返回值是多少(我只是把它们都放在一个文件中)
我可以使用 mkfifo
来解决这个问题吗?每个进程在进入fifo时都会有一个编号,并且他的返回值会按照先进先出的顺序绑定(bind)。
我试过这样的:
#!/bin/bash
mkfifo pipe1
(sleep 4 ; echo "my return value is $? " >> $pipe1 ) &
(sleep 6 ; echo "my return value is $? " >> $pipe1 ) &
(sleep 9 ; echo "my return value is $? " >> $pipe1 ) &
(sleep 2 ; echo "my return value is $? " >> $pipe1 ) &
(sleep 12 ; echo "my return value is $? " >> $pipe1 ) &
(sleep 4 ; echo "my return value is $? " >> $pipe1 ) &
但它不起作用。也许我没有使用 fifo,对吗?
最佳答案
只要您的输出足够短以适合单个写入调用(以避免交错):
for ((x=0; x<10; x++)); do
(sleep $((RANDOM % 10)); echo "My number is $x and my return value is $?") &
done >output.txt
如果这不够安全,您可以锁定:
for ((x=0; x<10; x++)); do
(sleep $((RANDOM % 10))
retval=$?
exec {lock_fd}>.output_lock # open the lockfile
flock -x "$lock_fd" # grab the lock
echo "My number is $x; my return value is $retval" # do the write
) & # lock released by subshell exit
done >output.txt
...替换 .output_lock
带有要用于协调的锁定文件的文件名。
请注意 {lock_fd}>.output_lock
是需要 bash 4.1 或更新版本的语法;对于较旧的 shell,您需要自己分配一个 FD 编号——例如,3>.output_lock
-- 并在调用 flock
时使用该号码稍后。
您还可以通过调用 wait
来避免整个锁定问题。依次在每个子进程(及其 PID)上从父进程收集它们的退出状态值。
即:
#!/bin/bash
declare -a pids=( )
for ((x=0; x<10; x++)); do
sleep $((RANDOM % 10)) &
pids[$x]=$!
done
for pid in "${!pids[@]}"; do
wait "$pid"
echo "Child with PID $pid exited with status $?"
done >output.txt
这样做的缺点是您不会在作业退出时立即获得输出——相反,即使作业以不同的顺序退出,反馈也会按进程 ID 的顺序给出。
当然,另一种方法是将每个作业的退出状态写入不同的文件。
for ((x=0; x<10; x++)); do
(sleep $((RANDOM % 10)); echo "My number is $x and my return value is $?" >"output.$x.txt") &
done
关于linux - bash如何在后台保存multiply进程的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29221925/