我有一个存储在变量中的命令。让我们假设变量$i
具有值:
cat -nT index.php |grep 'someregex'
Run Code Online (Sandbox Code Playgroud)
当我尝试通过键入执行上述变量$i
时失败,因为 shell 尝试将整个变量作为一个命令执行。我也尝试使用eval($i)
和添加$i
反引号。
如何让 shell$i
像执行命令一样执行?为什么它的工作方式不一样。
$i='echo hi'; $i
Run Code Online (Sandbox Code Playgroud)
是因为我不得不在单引号中进行某种修改吗?(因为你不能嵌套它们。)目前我的解决方案是
echo $i > /foo; . /foo
Run Code Online (Sandbox Code Playgroud)
但我不想为此创建一个文件,以后再删除它。
我的意思是“我在单引号中黑了我做了:
$i='cat index.php | grep -P '"'"'MYREGEXHERE'"'"
Run Code Online (Sandbox Code Playgroud)
Gor*_*son 18
简短回答:参见BashAQ #50:我试图将命令放入变量中,但复杂的情况总是失败!.
长答案:这是因为 bash 解析命令行的顺序。具体来说,它在扩展变量值之前查找管道和重定向之类的东西,并且不会返回并重新查找扩展值中的管道等。本质上,变量在解析过程的中途被替换,因此该值仅在执行前被中途解析。
为了解决这个问题,您需要回答@slhck 的问题:为什么命令首先存储在变量中?你试图解决的实际问题是什么?根据实际目标,有多种可能的解决方案:
不要将其存储在变量中,直接执行即可。存储命令供以后使用是很棘手的,如果您真的不需要,那就不要。
使用函数而不是变量。毕竟,这就是他们的目的:
i() { cat -nT index.php |grep 'someregex'; }
i
Run Code Online (Sandbox Code Playgroud)
这样做的主要缺点是您不能动态创建函数——您不能有条件地从函数中包含或排除代码(尽管函数本身可以具有在执行时选择的条件元素)。
使用eval
. 这应该被视为最后的手段,因为很容易出现意外行为。它本质上通过另一个完整的解析传递运行命令,因此所有管道等都得到了它们的全部含义——但这也意味着您认为只是数据的命令部分也将被解析并可能被执行。包含 shell 元字符(管道、分号、引号/撇号等)的文件名可能会产生奇怪的、有时甚至是危险的效果。如果你确实使用了eval
,至少用双引号引用字符串,否则它的内容基本上会被解析一次半,结果甚至更奇怪。
i="cat -nT index.php |grep 'someregex'"
eval "$i"
Run Code Online (Sandbox Code Playgroud)编辑:另一种标准的 store-a-command-in-a-variable 方法是使用数组而不是简单的变量。这使您可以毫无困难地存储带有复杂参数(例如包含空格)的命令,但不会存储诸如管道和重定向之类的东西。因此,数组方法在这种特殊情况下没有用。
归档时间: |
|
查看次数: |
31028 次 |
最近记录: |