如何在bash的后台保存multiply进程的返回值?

时间:2015-03-23 22:52:42

标签: linux bash

我试图在背景中保存每个进程的返回值并行运行并以不同的时间结束。

例如(这里的返回值在所有进程中都是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时都会有一个数字,并且他的返回值将与先进先出的顺序绑定。

我试过这样:

#!/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一起工作吧?

1 个答案:

答案 0 :(得分:1)

只要您的输出足够短以适合单个写入调用(以避免交错):

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