2009-06-08 97 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