調用存儲在變量中的命令的正確方法是什麼?
1和2之間是否有區別?如何執行存儲在變量中的命令?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
調用存儲在變量中的命令的正確方法是什麼?
1和2之間是否有區別?如何執行存儲在變量中的命令?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
在執行它們之前,Unix shell對每一行輸入進行一系列轉換。對於大多數貝殼,它看起來是這樣的(從bash
手冊頁拍攝):
使用$cmd
直接得到它通過你的命令中的參數擴展階段置換後,它經歷了所有的下列轉換。
使用eval "$cmd"
什麼也不做,直到引用刪除階段,其中$cmd
原樣返回,並作爲參數傳遞給eval
,其功能是在執行前重新運行整個鏈條通過。
所以基本上,它們在大多數情況下是相同的,並且在您的命令使用參數擴展的轉換步驟時會有所不同。例如,使用支架擴展:
$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz
如何在不寫'eval'的情況下執行'eval'$ cmd''$($ cmd)'?'$ {$ cmd}'? –
@StevenLu,其中沒有一個是等價的 - 故意如此:'eval '操作將數據解析爲語法;因此它非常安全敏感,並且隱含地執行它將是非常糟糕的形式。 –
我覺得宇把`符號在你的變量(帶有〜如果移按下)
這執行命令的輸出,例如,在ls -l的情況下會生成一條消息,如「找不到總」命令「(因爲total ...是ls -l的輸出的一部分,例如)所以這不是你想要的。 –
如果你只是做eval $cmd
當我們做cmd="ls -l"
(交互式和腳本),我們得到的預期的結果。在你的情況下,你有一個grep沒有模式的管道,所以grep部分將失敗並帶有錯誤消息。只要$cmd
會產生一個「找不到的命令」(或某些這樣的)消息。 因此,請嘗試使用eval並使用完成的命令,而不是生成錯誤消息的命令。
這只是錯誤打印。應該是「grep exception」。 –
然後使用eval,而不是$ cmd本身,因爲它可能不起作用(它在我的測試中並沒有在bash和zsh下),這就是eval的意思。 –
請參見[BashFAQ/050](http://mywiki.wooledge.org/BashFAQ/050)。 –