Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.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-如何并行地将输出写入多个变量?_Bash_Performance - Fatal编程技术网

Bash-如何并行地将输出写入多个变量?

Bash-如何并行地将输出写入多个变量?,bash,performance,Bash,Performance,我有一个大约需要100毫秒才能运行的命令,在存储其输出的同时,必须多次运行它,而不会对脚本造成任何延迟 非并行代码段: DISCSUBTITLE=$(quodlibet --print-playing "<discsubtitle>") TITLE=$(quodlibet --print-playing "<title>") ARTIST=$(quodlibet --print-playing "<artist>") ALBUM=$(quodlibet --p

我有一个大约需要100毫秒才能运行的命令,在存储其输出的同时,必须多次运行它,而不会对脚本造成任何延迟

非并行代码段:

DISCSUBTITLE=$(quodlibet --print-playing "<discsubtitle>")
TITLE=$(quodlibet --print-playing "<title>")
ARTIST=$(quodlibet --print-playing "<artist>")
ALBUM=$(quodlibet --print-playing "<album>")
STATE=$(quodlibet --status)

echo "$DISCSUBTITLE - $TITLE / $ARTIST / $ALBUM"
echo $STATE #actual program does regex processing on $STATE
这是我选择的解决方案,因为它是最简单也是最快的。在我的SSD上花费了大约0.16秒,在我的HDD上花费了0.18秒。加速比超过3倍。
我最初没有想到使用临时文件,因为我错误地认为写入磁盘会很混乱,而且需要花费太多时间。与其他“每天”的磁盘操作相比,这要快得多,这些磁盘操作的规模为许多兆字节,通常还涉及其他操作

  • 特定于程序。尽量减少通话。
  • LONG=$(quodlibet--打印播放)/
    " /  / ")
    #通过研究和摆弄,我发现--print playing命令
    #对于我的程序,在输出字符串时使用替换,类似于
    #标记语言,因此基本上可以打印任何信息
    #随你怎么想。
    状态=$(quodlibet--状态)
    #国家必须分开
    回声$LONG
    echo$状态
    
    这在我的机器上花费了大约0.21秒,这是我的备用解决方案。
    有些限制,并且严重依赖于所使用的程序

  • GNU并行/Parset
  • $(哪个env_parallel.bash)
    解析“DISCSUBTITLE标题艺术家专辑状态”:\
    quodlibet--打印播放“”“\
    quodlibet--打印播放“”“\
    quodlibet--打印播放“”“\
    quodlibet--打印播放“”“\
    “quodlibet--状态”
    echo“$DISCSUBTITLE-$TITLE/$ARTIST/$ALBUM”
    echo$状态
    
    这在我的机器上花费了大约0.35秒。这对我来说并不理想,但从技术上讲,利润率仍然相当快。

    其中一条评论提到它实际上是解决方案1的自动化版本。

    使用临时文件怎么样

    cmd1 > out1 &
    cmd2 > out2 &
    cmd3 > out3 &
    cmd4 > out4 &
    
    wait
    
    var1=$(< out1)
    var2=$(< out2)
    var3=$(< out3)
    var4=$(< out4)
    
    echo "$var1 $var2 $var3 $var4"
    
    cmd1>out1&
    cmd2>out2&
    cmd3>out3&
    cmd4>out4&
    等待
    var1=$(
    可能与
    read
    一起运行,因此您只需运行
    cmd
    一次:

    read a b c < <(cmd --printA --printB --printC)
    

    readabc<我不明白这个问题。您尝试过哪些代码,以及为什么您认为它不起作用?您发布的代码中没有类似的内容。@raissond'etre:除了Poshi所说的以外,您的示例代码没有将命令的任何输出存储在变量中。除此之外,如果一个命令的执行只需要十分之一秒,我认为通过并行化所有内容不会获得很多好处,因为这样会浪费额外的时间来设置并行进程。您可以做的是“捆绑”这些命令。例如,如果有10000个命令要执行,您可以创建100个文件,每个文件按顺序运行100个命令,并并行运行这些“主文件”
    parset
    是GNU Parallel较新版本的一部分。这基本上就是
    parset
    所做的,但它添加了GNU Parallel语法,并清理了临时文件。
    . $(which env_parallel.bash)
    parset "DISCSUBTITLE TITLE ARTIST ALBUM STATE" ::: \
        "quodlibet --print-playing '<discsubtitle>'" \
        "quodlibet --print-playing '<title>'" \
        "quodlibet --print-playing '<artist>'" \
        "quodlibet --print-playing '<album>'" \
        "quodlibet --status"
    
    echo "$DISCSUBTITLE - $TITLE / $ARTIST / $ALBUM"
    echo $STATE
    
    cmd1 > out1 &
    cmd2 > out2 &
    cmd3 > out3 &
    cmd4 > out4 &
    
    wait
    
    var1=$(< out1)
    var2=$(< out2)
    var3=$(< out3)
    var4=$(< out4)
    
    echo "$var1 $var2 $var3 $var4"
    
    read a b c < <(cmd --printA --printB --printC)