我试图在定界文档内运行命令时设置变量“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)"
,则需要使用<<\EOF
or<<'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 变量中count
。timeout
它本身并不是我的 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