例如,而不是做
start=`commandforstdout | awk {'print $2'}`
end=`commandforstdout | awk {'print $5'}`
有没有办法存储
`commandforstdout | awk {'print $2, $5'}`
分成两个不同的变量,而不必再次运行命令?只是为了提高效率...
答案 0 :(得分:5)
将read
内置使用流程替换:
read start end < <(commandforstdout | awk {'print $2, $5'})
甚至没有awk(感谢@gniourf_gniourf):
read -r _ start _ _ end _ < <(commandforstdout)
答案 1 :(得分:2)
这种无需协同处理或基本原理的便携式方法:
set -- $(commandforstdout | awk '{print $2, $5}')
start=$1 end=$2
如果您告诉我们commandforstdout
的输出,这可能会更容易。可能是那个
set -- $(commandforstdout)
start=$2 end=$5
甚至可以节省昂贵的叉子和管道。正如gniourf_gniourf正确地指出的那样,如果结果包含glob字符,则路径名扩展可能会受到阻碍。如果这是一个问题,请在第一个set -f
和set
之前使用set +f
,如果您稍后需要进行路径名扩展。
答案 2 :(得分:2)
补充现有的有用答案:
简单的管道解决方案(commandforstdout | read ...
)不起作用的原因是管道中的所有命令默认都在 sub shell 中运行,以便管道中的read
命令创建的变量在管道之后不可见。
但是,在 bash 4.2 + 上,启用 shell选项lastpipe
会导致 last 管道段在当前<中运行/ em> shell ,允许read
创建当前shell可见的变量。
示例:
# bash 4.2+: Turn on shell option that runs the *last* pipeline segment in the
# *current shell* rather than in a *subshell*.
shopt -s lastpipe
# Read the two words piped via stdin into two variables.
# Since option `lastpipe` is on, the variables are created in the *current* shell.
echo 'START END' | read -r start end
echo "[$start] [$end]" # -> '[START] [END]'
注意:lastpipe
仅在 off 的作业控制时有效,默认情况下在非交互式shell中为true(例如,在脚本中),但在交互式shell 中却不是这样;要以交互方式测试上述示例,您必须关闭作业控制(暂时):
set +m; shopt -s lastpipe && echo 'START END' | read -r start end; echo "[$start] [$end]"; set -m