我想创建一个并行运行多个命令的脚本。我希望它在我 git CTRL+C 时退出所有这些命令
我遇到的问题是,当我将第一个 ping 命令的输出通过管道传输到 bash 函数时,它不会打印退出日志。即包含 "rtt min/avg/max/mdev = 6.808/6.855/6.906/0.040 ms"
的日志
我怎样才能让它工作?谢谢:)
#!/bin/bash
trap terminate SIGINT
terminate(){
echo "terminating started"
pkill -SIGINT -P $$
echo "terminating finished"
exit
}
log () {
sed -e "s/^/[$1]: /"
}
#the rest of your code goes here
ping 1.1.1.1 |& log "first_log" &
ping bbc.com |& sed -e "s/^/[bbc_log]: /"&
wait
以下是日志:
dewi@pop-os:~/tmp/bashtest$ bash bashtest
[first_log]: PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
[first_log]: 64 bytes from 1.1.1.1: icmp_seq=1 ttl=56 time=9.37 ms
[first_log]: 64 bytes from 1.1.1.1: icmp_seq=2 ttl=56 time=9.31 ms
[bbc_log]: PING bbc.com(2a04:4e42::81 (2a04:4e42::81)) 56 data bytes
[bbc_log]: 64 bytes from 2a04:4e42::81 (2a04:4e42::81): icmp_seq=1 ttl=250 time=7.82 ms
[first_log]: 64 bytes from 1.1.1.1: icmp_seq=3 ttl=56 time=9.42 ms
[bbc_log]: 64 bytes from 2a04:4e42::81 (2a04:4e42::81): icmp_seq=2 ttl=250 time=6.32 ms
[first_log]: 64 bytes from 1.1.1.1: icmp_seq=4 ttl=56 time=9.32 ms
^C[bbc_log]: 64 bytes from 2a04:4e42::81: icmp_seq=3 ttl=250 time=6.66 ms
[bbc_log]:
[bbc_log]: --- bbc.com ping statistics ---
[bbc_log]: 3 packets transmitted, 3 received, 0% packet loss, time 2001ms
[bbc_log]: rtt min/avg/max/mdev = 6.317/6.930/7.816/0.641 ms
terminating started
terminating finished
dewi@pop-os:~/tmp/bashtest$
非常感谢:)
编辑:这是问题的一个简单版本:
$ cat tst.sh
#!/usr/bin/env bash
log() {
sed 's/^/[log]: /'
}
if [[ $1 == 1 ]]; then
ping 1.1.1.1 2>&1 | sed 's/^/[log]: /' &
else
ping 1.1.1.1 2>&1 | log &
fi
wait
$ ./tst.sh 1
[log]:
[log]: Pinging 1.1.1.1 with 32 bytes of data:
[log]: Reply from 1.1.1.1: bytes=32 time=20ms TTL=55
[log]:
[log]: Ping statistics for 1.1.1.1:
[log]: Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
[log]: Approximate round trip times in milli-seconds:
[log]: Minimum = 20ms, Maximum = 20ms, Average = 20ms
[log]: Control-C
$ ./tst.sh 2
[log]:
[log]: Pinging 1.1.1.1 with 32 bytes of data:
[log]: Reply from 1.1.1.1: bytes=32 time=59ms TTL=55
$
上面的两次运行大约在同一时间被中断。为什么第一个版本(直接调用 sed)会打印 ping 的最终统计信息,而第二个版本(通过函数调用 sed)则不会?
最佳答案
您在将 SIGINT 发送到 sed
的同时,也将其发送到 ping
。 sed
在看到 ping
的最终消息之前终止。
一个简单的解决方法是使用可以忽略 SIGINT 的 sed
版本。例如:
perl -p -e 'BEGIN{$SIG{INT}="IGNORE";} s/^/['"$1]: /"
对于 @EdMorton 提出的出色问题,我只想说 shell 中(通常是 Unix 中)的信号处理是变化无常的。该行为在很大程度上取决于事件的顺序。
关于bash - 当我通过 bash 函数进行管道传输时,为什么不显示命令退出日志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73089579/