2009-06-08 56 views
4

參數我有一個實用程序工作(unison,但是這不是重點)接受參數,如:操縱SH

$ unison -path path1 -path path2 -path path3 

我想寫出我可以運行像這樣的sh腳本:

$ myscript path1 path2 path3 

我希望符合POSIX標準的解決方案,但特定的bash也會很好。

我猜它應該是這樣的:

#!/bin/sh 
unison ${*//-path } 

但是,這是行不通的。

編輯:OK,我覺得我得到的東西:

#!/bin/bash 
PARAMS= 
for arg in "[email protected]" 
do 
    PARAMS+=" -path '$arg'" 
done 
unison $PARAMS 

的問題是在bash這隻作品,我敢肯定有一個更好的方式來引用參數。

+0

是你希望有一個不涉及`for`循環的單線解決方案? – eduffy 2009-06-08 14:49:34

+0

真的任何解決方案 – itsadok 2009-06-08 14:50:55

+0

引入單引號可能是一個壞主意。正如所寫的那樣,引用是由unison命令看到的,這不是你想要的。如果參數中沒有任何單引號,那麼使用單引號保護參數的外部是可以的 - 但您可能需要一個eval才能使其正常工作。 – 2009-06-08 15:05:05

回答

5

未選中,也可能是那樣簡單:

exec unison -path $1 -path $2 -path $3 

如果你沒有在你的路徑名中插入空格,那麼你可以處理的參數與可變數目:

arglist="" 
for path in "[email protected]" 
do 
    arglist="$arglist -path $path" 
done 
exec unison $arglist 

如果你的路徑名中有空格,那麼你必須更努力地工作;我通常使用稱爲escape自定義程序,它引述需要報價參數,eval

arglist="" 
for path in "[email protected]" 
do 
    path=$(escape "$path") 
    arglist="$arglist -path $path" 
done 
eval exec unison "$arglist" 

我注意到,使用Perl或Python將使處理參數用空格在它們更容易 - 但問題詢問殼。

在Bash中使用shell數組變量可能也是可行的 - 在數組中構建參數並將數組作爲參數傳遞給unison命令。

1

如果你想有一個嚴重的bash特定版本,你可以試試

 
#! /bin/sh 

eval eval exec \ 
    unison -path\\ \\\"{$(eval echo \\\"\\\${1..$#}\\\" | sed 's/ /,/g')}\\\" 

如果刪除所有的三反斜槓引用的字符,這變得更容易理解,但我不會殺風景通過解釋它:-)

主要的複雜性是處理文件名與空格。這說明了三重反彈引用和雙重評估。

4

如果使用Bash的數組,所有引用問題都會消失。

#!/bin/bash 
args=() 
for i in "[email protected]"; do 
    # With Bash >= 3: 
    args+=(-path "$i") 
    # +=() doesn't work in Bash 2 
    # args=("${args[@]}" -path "$i") 
done 
exec unison "${args[@]}" 
3

在bash中,你可以使用"${@/#/-path }"將與「-path」替換每個位置參數的開始。要表示字符串的結尾,請使用%而不是#

這是一個簡單的演示腳本,使用sed和重複的-e選項。(當然也有使用sed更有效的方法)

#!/bin/bash 
echo "Resulting arguments: ${@/#/-e }" 
sed "${@/#/-e }" 

並運行它像這樣:

$ echo abc | demo s/a/A/ s/b/B/ 

我們得到:

Resulting arguments: -e s/a/A/ -e s/b/B/ 
ABc 
1

這裏是你如何能令人滿意的報價你的角色:

job_strategy() 
{ 
    local p 
    for p in "[email protected]"; do 
    printf '-path\000%s\000' "$p" 
    done 
} 

job_process() 
{ 
    xargs -0 unison 
} 

job_strategy "path1" "path2" "path3" | job_process