我有以下命令行来检查文件系统的可用空间:
fs_used=`df -h /u01 | sed '1d' | sed '1d' | awk '{print $4}' | cut -d'%' -f1`
工作正常。它返回文件系统上已用空间的百分比(不带%符号)。
现在我需要让它变量并使用eval命令运行它。我尝试了以下但它不起作用(退出df:无效选项 - 'd')
df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print $4}' | cut -d'%' -f1"
fs_used=eval $df_cmnd
问题,我想,eval无法运行管道命令。真的吗? 是否有任何解决方法或替代方法来运行此代码?
答案 0 :(得分:7)
反斜杠 - 转义$
,并使用$()
:
# V V
df_cmnd="df -h \$fs1 | sed '1d' | sed '1d' | awk '{print \$4}' | cut -d'%' -f1"
fs_used=$(eval "$df_cmnd")
# ^^ ^
这将在您评估时使用fs1
的值。
但实际上,请don't use eval!改为使用shell函数:
df_cmnd(){
df -h "$1" | sed '1d' | sed '1d' | awk '{print $4}' | cut -d'%' -f1
}
fs_used=$(df_cmnd /u01)
然后你不必担心逃跑。
了解bash
如何解释您的df_cmnd
作业:
$ df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print $4}' | cut -d'%' -f1"
$ echo $df_cmnd
df -h | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1
# ^ ^
在我的情况下,fs1
为空,因此我df -h
部分获得了df
。在你和我的情况下,bash将$4
替换为其值,此处为空,因为我没有在带有四个参数的脚本中运行。因此,awk将打印整行,而不仅仅是第四个字段。
答案 1 :(得分:1)
我有eval
字符串的合法需求:一个辅助脚本运行带有复引号的复杂管道序列(例如--json-override='"key": "value"'
),长度超过460个字符。但是,当我使用--noop
运行它时,我想看到将要执行的命令,以可复制粘贴的形式手动执行。我想出了这个:
echo_eval () {
cmd=$(cat)
if ((noop)); then
echo "$cmd"
else
eval "$cmd"
fi
}
foo () { for arg; do echo "[$arg]"; done; }
echo_eval <<EOF
foo 1 2 "3 4" '"5 6"' " 7 " "\"8 9\"" | tac
EOF
exit 1
此文档的主要目的是跳过在已被'或'引号的字符串中使用'和'引号的所有陷阱(痛苦和痛苦)。
虽然我还没有对其进行广泛的测试,但它似乎打中了相关的复选框,例如管道,引号,引用包含空格的参数,保留引用的引号,转义的引号,参数中的前导/后缀空格等:
["8 9"]
[ 7 ]
["5 6"]
[3 4]
[2]
[1]
当noop
为真时,我得到:
foo 1 "2" "3 4" '"5 6"' " 7 " "\"8 9\"" | tac
这是逐字记录的命令,可复制粘贴以手动执行并产生相同的输出。
我们还可以使用<<'EOF'
禁用$
之前的任何echo_eval
的替换,但是如果确实需要在调用echo_eval
之前进行任何变量/命令替换,我们必须使用<<EOF
并转义所有以前不应该评估的$
。
已经说了这么多,我很高兴(a)听到是否存在陷阱(除了上述$
之外),并且(b)如果有问题,则可以找到更好的解决方案。