如何在变量中捕获 stderr 并通过管道传输 stdout

How to capture stderr in a variable and pipe stdout through

我正在尝试将 curl 响应的 headers(来自 stderr)存储在变量中,并将 body(来自 stdout)通过管道传输到 grep。

这是我目前的尝试:

{
  HEADERS=$(curl -vs $URL 2>&1 1>&3-)
  echo "$HEADERS"
} 3>&1 | grep "regex" >> filename
echo "$HEADERS"

当我 运行 使用 bash -x script.sh 的脚本时,我看到 + HEADERS='...' 具有预期的输出,但我无法使用 $HEADERS 或 [=14] 访问它们=] 内联组内外.

body get 按预期通过管道传输。

您丢失了 HEADERS 变量,因为使用了在子 shell 中分叉和运行管道命令的管道,而父 shell 没有看到在子 [=] 中创建的变量20=]s.

您可以通过临时文件执行此操作:

{ f=$(mktemp /tmp/curl.XXXXXX); curl -vs "$URL" 2>"$f" |
grep 'regex' >> filename; HEADERS="$(<$f)"; trap 'rm -f "$f"' EXIT;}

现在 HEADERS 变量将通过读取使用 mktemp 创建的临时文件填充到父 shell 本身。

anubhava correctly 一样,问题是您在子进程中设置 HEADERS,而不是在 shell 的主进程中设置。

您可以使用 Bash 的 process substitution 来避免该问题,而无需使用在 shell 中断时必须清理的临时文件:

HEADERS=""
{ HEADERS=$(curl -vs "$URL" 2>&1 1>&3-); } 3> >(grep "regex" > file)
echo "$HEADERS"

grep 子进程被进程替换隐藏了。 3>>(…)之间的space是必须的。