bash 变量作为命令:在执行前回显命令并将结果保存到变量中

zap*_*pee 0 variables bash curl eval

我正在执行一系列命令curl

  1. 我需要在执行之前回显该命令。
  2. 执行命令并将结果保存到 bash 变量中。
  3. 从执行结果中获取值并使用该值执行下一个curl。

它是这样的:

#  -----> step 1 <-----
URL="https://web.example.com:8444/hello.html"
CMD="curl \
        --insecure \
        --dump-header - \
        \"$URL\""

echo $CMD && eval $CMD
OUT="<result of the curl command???>"

# Set-Cookie: JSESSIONID=5D5B29689EFE6987B6B17630E1F228AD; Path=/; Secure; HttpOnly
JSESSIONID=$(echo $OUT | grep JSESSIONID | awk '{ s = ""; for (i = 2; i <= NF; i++) s = s $i " "; print s }' | xargs)

# Location: https://web.example.com:8444/oauth2/authorization/openam
URL=$(echo $OUT | grep Location | awk '{print $2}')

#  -----> step 2 <-----
CMD="curl \
        --insecure \
        --dump-header - \
        --cookie \"$JSESSIONID\" \
        \"$URL\""
echo $CMD && eval $CMD
OUT="<result of the curl command???>"
...

#  -----> step 3 <-----
...
Run Code Online (Sandbox Code Playgroud)

我只有一个问题step 2:将命令的完整结果保存curl到变量中,以便我可以解析它。

我尝试了很多不同的方法,但没有一个有效:

  • OUT="eval \$CMD"
  • OUT=\$$CMD
  • OUT=$($CMD)
  • ...

我错过了什么?

Soc*_*owi 5

对于非常基本的命令,OUT=$($CMD)应该可以工作。这样做的问题是,存储在变量中的字符串的处理方式与直接输入的字符串的处理方式不同。例如,echo "a"prints a,但是var='"a"'; echo $aprints "a"(注意引号)。由于这个原因和其他原因,您不应该将命令存储在变量中。

在 bash 中,您可以使用数组来代替。顺便说一句:常规变量的命名约定不是全部大写,因为这样的名称可能会意外地与特殊变量发生冲突。另外,您可能可以大大简化您的grep | awk | xargs.

url="https://web.example.com:8444/hello.html"
cmd=(curl --insecure --dump-header - "$url")
printf '%q ' "${cmd[@]}"; echo
out=$("${cmd[@]}")
# Set-Cookie: JSESSIONID=5D5B29689EFE6987B6B17630E1F228AD; Path=/; Secure; HttpOnly
jsessionid=$(awk '{$1=""; printf "%s%s", d, substr($0,2); d=FS}' <<< "$out")
# Location: https://web.example.com:8444/oauth2/authorization/openam
url=$(awk '/Location/ {print $2}' <<< "$out")

#  -----> step 2 <-----
cmd=(curl --insecure --dump-header - --cookie "$jsessionid" "$url")
printf '%q ' "${cmd[@]}"; echo
out=$("${cmd[@]}")

#  -----> step 3 <-----
...
Run Code Online (Sandbox Code Playgroud)

如果您有更多步骤,请将重复部分包装到一个函数中,如 Charles Duffy 建议的那样