当命令存储在变量中时,io 重定向不起作用

当命令存储在变量中时,io 重定向不起作用

以下命令可让我检查网页是否具有特定内容。除非找到内容,否则它不会输出任何内容。

curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'

问题是,当我将其添加到 shell 脚本中时,输出不再被抑制。

#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"

$TEST1
if [[ $? != 0 ]]; then
    #do something if exit status of last command not equal to zero
fi

如果我尝试将脚本的输出存储在变量 ( VAL1)中,我也会遇到同样的问题

#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"
VAL1+=$($TEST1)
echo "result should be blank or the found grep $VAL1"

为什么2>&1直接运行命令时可以按预期工作,但添加到脚本时输出将直接在命令行中?

更新

杰夫斯在评论中的暗示让我朝着正确的方向前进。接受的答案是正确的。我为脚本所做的工作是将我最初尝试分配给变量的代码移动到函数中并使用$( ... ).这样一切都按预期运行:

#!/bin/bash
# note that -z checks if variable is empty
test1() {
  VAL1=$(curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content')
  if [[ -z $VAL1 ]]; then
    VAL1=test1fail
  fi
}

test1
echo $VAL1

答案1

杰夫·夏勒的评论关联是在鼻子上。 bash 手册中的关键信息(https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

当执行一个简单的命令时,shell 从左到右执行以下扩展、赋值和重定向。

  1. 解析器标记为变量赋值的单词(命令名称前面的单词)和重定向保存以供以后处理
  2. 不是变量赋值或重定向的单词是扩大(看外壳扩展)。如果扩展后仍有任何单词,则第一个单词将被视为命令名称,其余单词将被视为参数。
  3. 执行重定向如上所述(参见重定向)。
  4. 每个变量赋值中“=”后面的文本在赋值给变量之前都会经过波形符扩展、参数扩展、命令替换、算术扩展和引号删除。

步骤 1 识别重定向并保存它们。
第 2 步是变量扩展发生的地方。

shell 在步骤 1 中看不到重定向。

还相关:我试图将命令放入变量中,但复杂的情况总是失败!

答案2

糟糕的解决方案是强制进行双重评估:

eval "$TEST1"

好的解决方案是按语义分割命令(url,内容):

curl -v --silent "$url" |& grep "$content"

注意:|&是语法糖2>&1 |

相关内容