lukuluku
lukuluku

Reputation: 4404

Bash redirect vs. pipe

I have following bash script:

#!/bin/bash

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

proxy_list="${1}"
url="google.com"
pool=5
timeout=2

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}"
            break
        fi
    done
}

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

wait

The script will either use the filename (${1}) 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 | ./curl_socks_tester.sh

I get this error and the script continues running:

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

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

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

The script stops and I get following message:

^CTerminated

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

Upvotes: 1

Views: 443

Answers (1)

Petr Skocik
Petr Skocik

Reputation: 60145

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 | ./curl_socks_tester.sh

./curl_socks_tester.sh 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.

Upvotes: 1

Related Questions