如何在后台作业中运行命令并等待 bash 脚本中的结果

如何在后台作业中运行命令并等待 bash 脚本中的结果

如何为特定命令生成一个进程并在其运行时捕获其输出?

例如,我想dd在一个块上执行操作,当它执行其工作并生成状态消息时,我会使用 dd 进度的输出执行其他操作。我厌倦了下面的脚本,但它永远不会停止打印:

#!/bin/bash

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 status=progress)&

while [ -z "$data" ]; do
 echo "waiting for data..." "${data}"
 # Do something else while $data is not returned
 sleep 0.1
done

我已经取得了一些进步,但仍然不是我想要的。

    #! /bin/bash
    
    varFileDone=$(mktemp)
    varFileOutput=$(mktemp)
    
    dd if=/dev/urandom of=/dev/null bs=4096 \
count=32768 status=progress 2<&1 >> $varFileOutput && echo 1 > $varFileDone &
    pid=$(pidof dd)
    
    while [[ ! -s $varFileDone ]];
    do
    
    data=$(cat $varFileOutput)
    echo "----->" "$data"
    if [[ -s $data ]];
      then
        echo "we have data"
        echo $data | cut -d"," -f3
      else
        echo "no data yet!"
      fi
      sleep 0.2
    done

答案1

你的问题有点模糊。在异步环境中设置变量的使用在这里不太有效,因为变量的值永远不可用于原始环境。

使用 & 符号的异步调用&可以替换为coproc。我建议查看 bash 的手册页,因为有一些工具采用这种格式。

使用示例:

#!/bin/bash

coproc COPROC ($(dd if=/dev/urandom of=/dev/null bs=4096 count=32768))

while [[ $COPROC ]]; do  
sleep 0.1
echo waiting!  
done

wait # unnecessary, but proves the asynchronous processes are actually complete
echo "Task done!"

答案2

你可以尝试:

dd if=/dev/urandom of=/dev/null bs=4096 count=32768 & 2>&1 > /tmp/tmp
pid=$(ps|grep dd|awk '{print $1}')
while [[ ! "" = "$pid" ]]
do     
    # Do something else while dd is still writing

    grep "," /tmp/tmp | grep -v "+"|awk '{$2" "$3}'
done

答案3

如果你不想看到dd命令输出,你可以添加一个重定向,如下所示:

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 2>&1 /dev/null)

2>&1用于重定向输出 AND 错误。

只需修改您想要的输出(替换/dev/null为任何其他文件)。您可以使用tail命令检查该过程中生成的输出,即tail -f /your/output/file

相关内容