我正在尝试解析发送到shell脚本的参数。例如,发送到脚本的值如下:
-to someone@somewhere.com -a file1.txt file2.txt "new file.txt"
我可以解析字符串,以便将-a
作为我的运算符,但我想重新格式化参数部分file1.txt file2.txt "new file.txt"
,使其看起来像'file1.txt' 'file2.txt' 'new file.txt'
,以便我可以传递它下到zip实用程序。
现在我使用以下内容来解析参数,但它没有得到我想要的结果。它很接近但不太正确。
for file in `echo $PARM`
do
FILE_LIST="$FILE_LIST '"$file"'"
done
这给了我'file1.txt' file2.txt' 'new' 'file.txt'
我如何重做上面的代码来给我我想要的东西。
谢谢
答案 0 :(得分:1)
首先,您需要了解shell解析命令行时的操作顺序。这是一个部分列表:首先,它解释引号和转义,然后删除它们(在它们产生效果之后),然后扩展任何变量引用(和类似的东西,如反引号表达式),单词拆分和通配符 - 扩展扩展变量值,然后最终将所有结果视为一个命令及其参数。
这对你要做的事情有两个重要的含义:当你的脚本收到它的参数时,它们就不再有引号;引号产生了影响(new file.txt
是一个参数而不是两个),但引号本身已经消失。另外,在变量中加入引号是没用的,因为当变量被扩展并且引号是命令行的一部分时,它们做任何有用的事情为时已晚 - 它们不被解析为引号,它们是只是作为参数的一部分传递给命令(你不想要)。
幸运的是,答案很简单(Stephen P在他的评论中总结了这一点):在所有变量引用周围加上双引号。这可以防止分词和通配符扩展阶段弄乱它们的值,这意味着作为单个参数(例如new file.txt
)传递给您的脚本的任何内容都作为单个参数传递。如果您需要传递所有参数,请使用"$@"
。如果您只需传递某些内容,则可以使用shift
删除选项,然后"$@"
将传递其余选项,或使用例如"${@:4}"
传递从#4开始的所有参数,或"${@:4:3}"
传递从#4开始的三个参数。