以下代码工作正常
#!/bin/bash
while true; do
echo $(pwd | awk '{print "dir: "$1}')
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
但我需要命令在变量中,就像这样.
#!/bin/bash
COMMAND=pwd | awk '{print "dir: "$1}'
while true; do
echo $($COMMAND)
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
第一个片段执行正常,并打印出类似的东西dir: /present/directory.第二个片段只打印空白行.为什么这样,我该如何解决?
我使用的命令没有意义.我只需要使用管道并选择这些命令来演示它.
如果你喜欢危险的生活,答案是eval:
#!/bin/bash
COMMAND="pwd | awk '{print \"dir: \"\$1}'"
while true
do
echo $(eval $COMMAND)
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
为什么危险?eval如果您接受来自天真(更不用说恶意)用户的命令字符串,那么很难控制正在发生的事情.还要注意我必须引用包含命令的字符串.
为什么问题中的第2版没有工作?
COMMAND=pwd | awk '{print "dir: "$1}'
Run Code Online (Sandbox Code Playgroud)
这句话并没有按照你的想法做到,直言不讳.
它是一个管道,第一个'命令'是字符串赋值,它COMMAND=pwd被视为空命令的环境变量,它不发送任何数据awk.完成后,值in $COMMAND是一个空字符串(因为子管道与管道一起使用,因为COMMAND=pwd只有在执行(空)命令时才应用),所以循环回应执行空字符串的结果 -也是一个空字符串.因此空白行.
这对我有用,但我在AWK打印输出中添加一个标签时遇到问题,我认为这是因为逃逸了.如果我有
COMMAND="ls -l | awk '{print \$8 \$9}'",我将如何\t在$8和之间插入一个标签$9?
哎哟,哎呀!
如果你有在的源标签$8和$9,awk就会把它当作普通的白色空间和粘贴$8,并$9在输出在一起.要在输出中获取选项卡,您需要包含选项卡的带引号的字符串,或者包含\t两个字段之间的带引号的字符串,或者您将使用printf()带有合适格式字符串的字符串.
因此,原则上,您可能想要:
COMMAND='ls -l | awk '\''{printf "%s\t%s\n", $8, $9}'\'
Run Code Online (Sandbox Code Playgroud)
我已经切换到字符串周围的单引号,因为它们更容易理解.无论您使用单引号还是双引号,命令本身都包含两者,因此您必须担心如何进行转义.该'\''序列是如何嵌入一个单引号变成一个单引号字符; 第一个单引号结束当前单引号字符串; 反斜杠单引号添加单引号,最后一个单引号重新启动单个字符串.最后的序列'\'也可以写'\''',但最后两个引号是一个零长度的单引号字符串,所以我放弃它们.
这会产生带有标签的不错输出; 您可以通过运行验证:
eval $COMMAND
Run Code Online (Sandbox Code Playgroud)
在echo $(eval $COMMAND)完全撤消所有小心间距,压扁文件和时代的整个列表与用空格从下分隔每个"单词"单行.
您可以通过强制echo尊重间距(和换行符)来解决该问题:
echo "$(eval $COMMAND)"
Run Code Online (Sandbox Code Playgroud)
但是这提出了"为什么不只使用eval $COMMAND?"的问题.
(测试:bash 3.2.48 Mac OS X 10.7.4.)
| 归档时间: |
|
| 查看次数: |
2094 次 |
| 最近记录: |