在heredoc中设置变量并在外部使用它们

在heredoc中设置变量并在外部使用它们

我试图在定界文档内运行命令时设置变量“count”并设置超时,但我无法在定界文档之外获取“count”变量。

我怎样才能做到这一点?

  • 我的脚本更复杂,但我认为得到答案就足够了。

    timeout 10 bash << EOC
       count=$(ls -l /tmp/ | wc -l)
    EOC
    
    echo "count: $count"
    

答案1

你不能。在子 shell 中分配的变量对父 shell 没有影响。

改为这样做:

count=$(timeout 10 ls -l /tmp/ | wc -l)
echo "count: $count"

答案2

你尝试做的事情是行不通的,你必须寻找其他方法。当你运行另一个程序时,它有自己的内存空间,它不能影响当前shell中的变量。即使其他程序恰好是您正在运行的同一 shell 的实例,情况也是如此。

使用此处文档而不bash -c改变这一事实。你的例子相当于timeout 10 bash -c "count=$(ls -l /tmp/ | wc -l)". (顺便说一句,它ls -l /tmp/ | wc -l在外壳中运行,而不是在bash您生成的实例中运行:如果您想做与 等效的操作timeout 10 bash -c "count=$(ls -l /tmp/ | wc -l)",则需要使用<<\EOFor<<'EOF'或类似的命令。)

如果您只需要获取一个变量的值,可以使用命令替换:

count=$(timeout 10 bash -c '…')

如果需要设置许多变量或数组,则需要进行一些编码和解码。您可以让 bash 为您做这件事:declare -p foo bar打印出一种定义方式foo,并bar为调用 shell 正确引用该方式。

eval "$(bash -c '…; declare foo bar')"

请注意,这会在本地声明变量,因此如果您在函数中运行它,则函数返回时变量将不可用。如果您需要在返回时使用这些变量,则需要使用 再次分配它们declare -g;这仅适用于标量:

f () {
  eval "$(bash -c '…; declare foo bar')"
  declare -g foo="$foo" bar="$bar"
}

或者,如果您知道变量的值不能包含换行符,请declare -… 从 的输出中的每行开头删除declare -p

答案3

我认为你无法实现这一目标。最大的问题是您有一个bash进程评估管道,然后将该管道的值存储在 shell 变量中counttimeout它本身并不是我的 Arch 笔记本电脑上内置的 shell,因此还有第三级进程。由于timeout分叉了它等待的命令,因此存在第三级进程。

那是 shell-that-invokes-timeout -> timeout -> bash-invoked-by-timeout -> value-of-count

在我看来,您需要重新安排 shell 脚本才能使用值count(或您想要完成的任何事情)。

如果您确实需要timeout命令,您可能应该将命令的输出发送到文件,然后读取该文件:

if timeout ls -l /tmp > /tmp/some.well.known.name
then
    VAR=$(wc -l /tmp/some.well.known.name)
else
    : handle timeout
fi

相关内容