有人可以解释为什么我不能将 cut 命令存储在变量中吗?
user:~$ echo "foo bii doo" | cut -d ' ' -f 2
bii # as expected
# now put cut command into a variable:
user:~$ c="cut -d ' ' -f 2"
user:~$ echo "foo bii doo" | $c
cut: "'": No such file or directory
user:~$ c="cut -d \ -f 2"
user:~$ echo "foo bii doo" | $c
foo bii doo
这不是一般的引用问题,因为 tr 有效:
user:~$ t="tr -d 'oo'"
user:~$ echo "foo bii doo" | $t
f bii d
(我在 Debian 12 上使用 bash)
已经用其他方式解决了这个问题。我只是想知道为什么我浪费了 3 个小时的调试时间:)
答案1
在某种程度上,这不是一个引用问题,而是一个扩展问题。变量扩展不是文本替换,从变量中获取的数据是不是解析为代码,这意味着引号、反斜杠转义或任何其他 shell 语法都不会被处理。相反,扩展值是在空白(任何空白)上进行分词的。这意味着您不能使用分词在一个字符串中存储多个任意字符串。
tr
您使用的命令似乎工作,因为在其参数中添加单引号不会改变它对o
s 的作用。正如克里斯戴维斯在评论中提到的,如果你这样做:
$ t="tr -d 'oo'"
$ echo "don't forget" | $t
dnt frget
tr
您将看到引号已包含在要删除的字符列表中。tr
得到了论据'oo'
,而不是论据oo
。如果您想tr
删除空格,则会遇到问题,与以下情况相同cut
:
$ t="tr -d ' '"
$ echo "don't forget" | $t
usage: tr [-Ccsu] string1 string2
tr [-Ccu] -d string1
tr [-Ccu] -s string1
tr [-Ccu] -ds string1 string2
它尝试tr
使用三个参数-d
、'
和来运行'
,这与它应该如何使用不匹配,因此它会打印使用帮助。
做到这一点的方法是创建一个函数,例如:
c() {
cut -d \ -f 2
}
echo "foo bii doo" | c
给予bii
。
看: