我正在寻找一种并行运行函数的方法,并准确地知道所有函数实例何时完成. 我添加了一个微调函数(该函数的实例运行时间不同,取决于变量,因此我需要在屏幕上看到一些内容),并try 了以下方法:

for a in "${ARRAY[@]}"; do
    spin='/-\|'
    while true; do
        i=$(( (i+1) %4 )); printf "\r[ ${spin:$i:1} ] "; sleep .3;
    done & someFunction & 
    kill $!; trap 'kill $!' SIGTERM
done

someFunction美元并不管用.我猜想是因为如果它被作为someFunction &触发,它会被下一个代码行立即杀死.此外,在脚本结束后,微调工具将永远在CLI上工作.

怎样才能同时运行someFunction次,直到最后一次完成,并保持旋转到那时?

推荐答案

由于Bash管理后台进程的方式,通常有一种很小的可能性,即通过PID杀死一个进程会杀死错误的进程.如果您使用的是Bash 4.3(2014年发布)或更高版本,请try 以下免删除代码:

#! /bin/bash -p

# FIXME: Define the 'args' array and the 'someFunction' function

# Run a spinner as a coprocess
coproc spinner \
{
    declare -r spin='/-\|'
    declare i=0
    while read -r -t 0.3 _; (( $? > 128 )); do
        printf '\r[ %s ] ' "${spin:i++%4:1}" >&2
    done
}

# Disown the spinner coprocess so 'wait' will not wait for it to exit
disown %% 

for a in "${args[@]}"; do
    someFunction "$a" & 
done

# Wait for all background processes (except the disowned spinner) to exit
wait

# Close the pipe to the spinner.  It will read EOF and close.
exec {spinner[1]}>&-
  • coprocess的速度运行旋转器,可以通过关闭其输入管道而不是终止它来停止它.它还使disown微调程序进程成为可能,因此wait不会等待它退出.
  • read文档中所述,如果read -r -t 0.3 _在0.3秒内无法读取输入行,则它将返回大于128的状态.使用read代替sleep作为微调器中的延迟,避免了 for each 延迟运行子进程,从而节省了资源.
  • exec {spinner[1]}>&-关闭通向协进程的管道(写入端).这将导致协同进程中的read以低于128的状态返回,从而导致协同进程立即退出.在没有显式关闭管道的情况下,协进程将继续运行,直到顶级进程退出(此时操作系统将自动关闭管道).(因此,如果顶级进程在wait之后立即退出,则显式关闭是不必要的,但我无论如何都会这样做,以允许稍后添加更多代码(或者将代码粘贴到更大的程序中).)
  • exec {spinner[1]}>&-在早于4.3的Bash版本中不起作用.解决Bash版本回到4.0的问题的一种方法是将其替换为eval "exec ${spinner[1]}>&-".最好避免使用eval(参见Why should eval be avoided in Bash, and what should I use instead?),但在这种情况下,我不知道有什么替代方法可以用于Bash4.0.
  • 最好避免ALL_UPERCASE变量名,因为这可能会与shell 编程中使用的大量特殊ALL_UPERCASE变量发生冲突.请参见Correct Bash and shell script variable capitalization.这就是为什么我将原始代码中的ARRAY替换为args.

Linux相关问答推荐

获取Perl文件::Tail开始在最后流传输文件

无法在Raspberry PI 3 Model B上分配256TB的虚拟内存

PERF显示不应该执行指令的内核的用户空间周期

使用信号处理程序实现Hibernate 功能

ShellScript,有更好的方法来查找具有特定名称和日期的文件吗?

Linux:用户态线程在执行系统调用时是否有更高的优先级?

在 bash 中获取目录或文件的基本名称的快速且正确的方法

将行转换为一条

从 curl 命令输出中获取值

问题:Virtio rpmsg 总线 virtio0:收到的 msg 没有收件人 - 在 Yocto Hardknott - imx7d-pico

CHMOD 755 与 750 权限集之间的差异

Linux 应用程序分析

使用 rc.local 运行脚本:脚本有效,但在启动时无效

为什么 JVM 报告的已提交内存比 linux 进程驻留集大小更多?

rm 没有释放磁盘空间

如何在字符串中查找子字符串(或如何 grep 变量)?

用于提取 IP 地址的 Linux bash 脚本

如何在 linux 中使用 CMake 和 Kdevelop 编译 GLUT + OpenGL 项目?

仅当文件存在于 shell 脚本中时才移动

Linux 上 POSIX AIO 和 libaio 的区别?