我试图将rsync
输出通过管道传输到自定义函数,并使用它来相应地输出自定义信息。
log_output() {
while read -r dir; do
last_slash_index=$(echo $dir | awk -F "/" '{print length($0)-length($NF)}')
echo ${dir:(($last_slash_index))}
done
}
rsync -avnh "/src/" "/dest" | log_output
在这个特定的实例中,它输出目录的最后一个不包含任何/
.问题是,当我尝试ctrl+c
终止进程时,子进程不会停止。即使rsync
已停止(正如我在输出中看到的那样),我自己的解析结果仍会输出到终端一段时间。我可以在代码中添加任何内容,以便当我按下 时ctrl+c
,一切都会终止吗?
答案1
control来自+的信号c可能需要一段时间才能让前台进程组中的所有进程做出响应,特别是当系统非常繁忙或进程在 I/O 上被阻塞时。 (这假设终端尚未配置为不生成信号。termios
有关详细信息,请参阅有关该ISIG
标志的手册。但我在您的问题中没有看到这方面的迹象。)在实时操作系统上计时可能会更好,尽管默认情况下unix往往不是这样,并且如果当你的“停止,现在!”时文件写了一半发生了,你会...停止并可能破坏输出吗?等待一段时间希望 I/O 刷新?还要多久?
信号处理程序(trap
在 shell 中,或者在接口之上构建的任何其他东西sigaction(2)
)将使事情变得复杂,复杂的前台进程组(shell 管道)也会使事情变得复杂。作为基线,您可能会看到control+的行为方式c;yes
并且cat
不应该做任何复杂的事情:
$ yes | cat
但是,您的终端可能正忙于显示 的所有输出yes
,因此响应速度可能很慢。该因素可以通过以下方式删除:
$ yes | cat > /dev/null
甚至
$ yes > /dev/null
control如果对+ 的响应很慢c,那么您的系统可能正忙于运行其他东西?
否则,管道到像这样的不太快的语言会bash
为每行输入加上一些其他代码创建一个新的 echo awk 管道,速度会更慢,特别是如果系统不太擅长分叉大量进程的话。将输出传输到awk
脚本(或其他编程语言)会更有效,该脚本本身可以完成所有计算,更重要的是取代缓慢且有问题 while read
循环进入bash
.这样,control+c就会得到更快的响应,并且会使用更少的 CPU。
$ echo /etc/passwd | awk -F "/" '{print $0, length($0)-length($NF)}'
/etc/passwd 5
$ dir=/etc/passwd; echo ${dir:5}
passwd
$ echo /etc/passwd | awk -F/ '{print $NF}'
passwd
control所以用+尝试的另一件事c可能会更简单一些
rsync -avnh /src/ /dest | awk -F/ '{print $NF}'
这看起来与所有 shell 函数正在执行的操作类似,并且它对 CPU 的效率应该要高得多。