【问题标题】:Bash redirect vs. pipeBash 重定向与管道
【发布时间】:2025-11-26 12:10:02
【问题描述】:

我有以下 bash 脚本:

#!/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

脚本将使用文件名 (${1}) 作为输入,如果没有提供位置参数,则使用标准输入。

(PIPE) 如果我按如下方式运行脚本并尝试在运行时使用 CTRL+C 将其终止:

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

我收到此错误,脚本继续运行:

./curl_socks_tester.sh: line 1: kill: (-21325) - 没有这样的进程

(REDIRECT) 或者像这样运行命令并使用 CTRL+C 终止脚本:

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

脚本停止,我收到以下消息:

^C终止

为什么陷阱在使用重定向时能够杀死所有子进程,但使用管道却失败了?

【问题讨论】:

    标签: linux bash unix redirect pipe


    【解决方案1】:

    bash 运行作业的方式,管道中的第一个链接成为组长(您应该能够通过ps 进行验证)。

    因此,在:

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

    ./curl_socks_tester.sh不是组长,所以kill -- -$$是无效的。

    如果您可以确定 shell 脚本是其进程组的领导者,您只能在脚本中使用 kill -- -$$

    【讨论】: