运行 带有 eval 的管道命令
Run piped commands with eval
我有以下命令行来检查文件系统的空闲 space:
fs_used=`df -h /u01 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1`
它工作正常。它 returns 已用 space 在文件系统上的百分比(没有 % 符号)。
现在我需要使用 eval 命令 使其成为可变的 运行。我尝试了以下但它不起作用(使用 df 退出:无效选项 -- 'd')
df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1"
fs_used=eval $df_cmnd
我猜,问题是 eval 不能 运行 管道命令。真的吗?
是否有任何解决方法或替代方法来制作此代码 运行?
反斜杠转义 $
,并使用 $()
:
# 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 "" | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1
}
fs_used=$(df_cmnd /u01)
那就不用担心转义了
说明
看看 bash
如何解释你的 df_cmnd
作业:
$ df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1"
$ echo $df_cmnd
df -h | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1
# ^ ^
在我的例子中,fs1
是空的,所以我只得到 df
部分的 df -h
。在您和我的情况下,bash 将
替换为它的值,此处为空,因为我不是 运行 在具有四个参数的脚本中。因此,awk 将打印整行而不仅仅是第四个字段。
我有合法需要 eval
-ing 一个字符串:一个助手脚本 运行s 一个复杂的管道序列,带有双引号(例如 --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
此处文档的主要目的是跳过在已经用 ' 或 " 引用的字符串中使用 ' 和 " 引号的所有陷阱(痛苦和痛苦)。
虽然我没有对其进行广泛的测试,但它似乎选中了相关的复选框,例如管道、引用、引用包含 space 的参数、保留引号、转义引号、leading/trailing space 参数等:
["8 9"]
[ 7 ]
["5 6"]
[3 4]
[2]
[1]
当 noop
为真时,我得到:
foo 1 "2" "3 4" '"5 6"' " 7 " "\"8 9\"" | tac
这是逐字命令,可复制粘贴以供手动执行并产生相同的输出。
我们还可以使用 <<'EOF'
禁用 echo_eval
之前的任何 $
替换,但是如果任何 variable/command 替换确实需要在调用 [=19 之前发生=],我们必须使用 <<EOF
并转义之前不应该计算的所有 $
。
说了这么多,我很乐意 (a) 听听是否有陷阱(除了上面提到的 $
)和 (b) 如果有的话,找到更好的解决方案。
我有以下命令行来检查文件系统的空闲 space:
fs_used=`df -h /u01 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1`
它工作正常。它 returns 已用 space 在文件系统上的百分比(没有 % 符号)。
现在我需要使用 eval 命令 使其成为可变的 运行。我尝试了以下但它不起作用(使用 df 退出:无效选项 -- 'd')
df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1"
fs_used=eval $df_cmnd
我猜,问题是 eval 不能 运行 管道命令。真的吗? 是否有任何解决方法或替代方法来制作此代码 运行?
反斜杠转义 $
,并使用 $()
:
# 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 "" | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1
}
fs_used=$(df_cmnd /u01)
那就不用担心转义了
说明
看看 bash
如何解释你的 df_cmnd
作业:
$ df_cmnd="df -h $fs1 | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1"
$ echo $df_cmnd
df -h | sed '1d' | sed '1d' | awk '{print }' | cut -d'%' -f1
# ^ ^
在我的例子中,fs1
是空的,所以我只得到 df
部分的 df -h
。在您和我的情况下,bash 将 替换为它的值,此处为空,因为我不是 运行 在具有四个参数的脚本中。因此,awk 将打印整行而不仅仅是第四个字段。
我有合法需要 eval
-ing 一个字符串:一个助手脚本 运行s 一个复杂的管道序列,带有双引号(例如 --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
此处文档的主要目的是跳过在已经用 ' 或 " 引用的字符串中使用 ' 和 " 引号的所有陷阱(痛苦和痛苦)。
虽然我没有对其进行广泛的测试,但它似乎选中了相关的复选框,例如管道、引用、引用包含 space 的参数、保留引号、转义引号、leading/trailing space 参数等:
["8 9"]
[ 7 ]
["5 6"]
[3 4]
[2]
[1]
当 noop
为真时,我得到:
foo 1 "2" "3 4" '"5 6"' " 7 " "\"8 9\"" | tac
这是逐字命令,可复制粘贴以供手动执行并产生相同的输出。
我们还可以使用 <<'EOF'
禁用 echo_eval
之前的任何 $
替换,但是如果任何 variable/command 替换确实需要在调用 [=19 之前发生=],我们必须使用 <<EOF
并转义之前不应该计算的所有 $
。
说了这么多,我很乐意 (a) 听听是否有陷阱(除了上面提到的 $
)和 (b) 如果有的话,找到更好的解决方案。