2013-04-01 194 views
2

如何將命令作爲參數傳遞給bash腳本? 在下面的腳本中,我試圖做到這一點,但它不起作用!將命令作爲參數傳遞給bash腳本

#! /bin/sh 

if [ $# -ne 2 ] 
then 
    echo "Usage: $0 <dir> <command to execute>" 
    exit 1; 
fi; 

while read line 
do 
    $($2) $line 
done < $(ls $1); 

echo "All Done" 

該腳本的樣本用法是

./myscript thisDir echo 

執行上述呼籲應該呼應的所有文件的名稱中thisDir目錄。

+0

嘗試'EVAL 「$ 2」' - http://www.linuxquestions.org/questions/programming-9/bash-script-passing-command-as-string-476664/ –

+0

@DavidStarkey嗯,我試過'eval'(以及下面建議的與'eval'有關的pther解決方案),都沒有工作。 –

回答

0

你可以嘗試:(在你的代碼)

echo "$2 $line"|sh 

eval

eval "$2 $line" 
+0

不適合我。當我用'myscript thisDir cat'調用腳本時,這意味着它應該'cat'指向目錄中的所有文件,它沒有 –

+0

任何錯誤信息? – Kent

+0

不,沒有任何錯誤。當我運行腳本時,它只是列出了目錄中的所有文件,儘管我確實指定了「cat」作爲命令。 –

1

你的命令 「echo」 命令是 「隱藏」 在其argments子殼內$線。

我想我明白你什麼企圖與$($2),但它可能是矯枉過正,除非這並不是故事的全部,所以

while read line ; do 
    $2 $line 
done < $(ls $1) 

應與thisDir echo你的榜樣工作。如果你真的需要CMD-替代和子shell,然後把你的論點,使他們能夠看到對方:

$($2 $line) 

而作爲D.S.提到,您可能需要eval任一前。

IHTH

0

第一大問題:$($2) $line本身執行$2作爲命令,然後嘗試與$line作爲參數傳遞給它運行它的輸出(如果有的話)作爲另一個命令。你只需要$2 $line

第二大問題:while read ... done < $(ls $1)不會從文件名列表中讀取,它會嘗試輸出ls指定的文件內容 - 根據具體情況,這會以任何方式失敗。進程替換(while read ... done < <(ls $1))會做或多或少的你想要的,但它是一個僅限bash的功能(即你的必須啓動腳本#!/bin/bash而不是#!/bin/sh)。無論如何這對parse ls是一個壞主意,你應該幾乎總是使用shell glob(*)代替。

該腳本還有一些其他潛在的問題與文件名空間(使用$line沒有雙引號周圍,等),怪異的風格怪異(你不需要;在shell行中的末尾)。這裏是我的刺在改寫:

#! /bin/sh 

if [ $# -ne 2 ]; then 
    echo "Usage: $0 <dir> <command to execute>" 
    exit 1 
fi 

for file in "$1"/*; do 
    $2 "$file" 
done 

echo "All done" 

注意,我沒把周圍$2雙引號。這允許您指定多字命令(例如,./myscript thisDir "cat -v"將被解釋爲運行帶有-v選項的cat命令,而不是嘗試運行名爲"cat -v"的命令)。將第一個參數之後的所有參數作爲命令及其參數,實際上會更靈活一些,從而可以讓您./myscript thisDir cat -v,​​等:

#! /bin/sh 

if [ $# -lt 2 ]; then 
    echo "Usage: $0 <dir> <command to execute> [command options]" 
    exit 1 
fi 

dir="$1" 
shift 

for file in "$dir"/*; do 
    "[email protected]" "$file" 
done 

echo "All done" 
相關問題