lukuluku lukuluku - 3 years ago 95
Linux Question

Bash redirect vs. pipe

I have following bash script:


trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM


check_proxy() {
local socks_proxy="${1}"
for retry in {0..2}; do
time_connect="$(curl ${url} --socks5 ${socks_proxy} -m${timeout} -o /dev/null -s -w %{time_connect})"
if [ $? -eq 0 ]; then
echo "${socks_proxy} (${time_connect}s) retries=${retry}"

while read proxy; do
while true; do
if [ "$(jobs -rp | wc -l)" -lt "${pool}" ]; then
check_proxy "${proxy}" &
wait -n
done < "${proxy_list:-/dev/stdin}"


The script will either use the filename (
) as input, or stdin if no positional parameter was provided.

(PIPE) If I run the script as follows and try to kill it with CTRL+C during runtime:

cut -f1 -d' ' data/socks_tested_sorted.list | ./

I get this error and the script continues running:

./ line 1: kill: (-21325) - No such process

(REDIRECT) Alternatively running the command like this and killing the script using CTRL+C:

./ <(cut -f1 -d' ' data/socks_tested_sorted.list)

The script stops and I get following message:


Why is the trap able to kill all child-processes when using redirect but it fails using a pipe?

Answer Source

The way bash runs jobs, the first link in the pipe-line becomes the group leader (as you should be able to verify with ps).

Consequently, in:

cut -f1 -d' ' data/socks_tested_sorted.list | ./

./ is not the group leader and so kill -- -$$ from it is invalid.

You can only use kill -- -$$ in a script if you can be sure the shell script is the leader of its process group.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download