大家好,提前致谢。
我在论坛上搜索了我的情况,但无法找到解决方案。我有一个在命令行传递参数/选项/参数的脚本。其中一个值中有一个空格,我将其放在双引号中。提供一个例子可能会更容易。请原谅我对参数/选项/参数的使用。
$: ./test1.ksh -n -b -d "Home Videos"
我的问题是将变量设置为“家庭视频”并将其一起使用。在我的示例中,-d 是指定一个目录。并非所有目录都有空格,但在我的例子中有些目录有空格。
这是我的代码示例,但它没有按我的预期工作。
#!/bin/ksh
Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}
SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
case $1 in
-[dD])
shift
export DirectoryName=$1
;;
-[nN])
export Var1=No
shift
;;
-[bB])
export Var2=Backup
shift
;;
*)
shift
;;
esac
done
Function2
}
Function2()
{
echo "Directory Name: ${DirectoryName}"
}
Function1 $*
当我运行此命令时,我仅获得 DirectoryName 的“Home”而不是“Home Videos”。见下。
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 5
Function1 Args: -n -b -d Home Videos
Number of Args in SetArgs: 5
SetArgs Args: -n -b -d Home Videos
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home
我所期待但未能实现的是:
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 4
Function1 Args: -n -b -d "Home Videos"
Number of Args in SetArgs: 4
SetArgs Args: -n -b -d "Home Videos"
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home Videos <-- Without double quotes in the final usage.
我能得到的任何帮助都将不胜感激...我尝试转义双引号,但没有成功。
感谢您花费时间和精力帮助我解决这个问题。
问候,丹尼尔
答案1
使用$*
或$@
不加引号绝不说得通。
"$*"
是位置参数与 的第一个字符(或字节,取决于 shell)的串联$IFS
,"$@"
是位置参数的列表。
当不加引号时,它是相同的,但会像任何其他不带引号的参数扩展一样进行 split+glob (或仅使用 删除空zsh
)(某些 shell 也会分隔参数,$*
即使 if$IFS
为空)。
这里你想传递参数列表按原样到你的函数,所以它是:
SetArgs "$@"
[...]
Function1 "$@"
请注意,对于 ksh88,$IFS
必须包含空格字符(默认情况下)才能正常工作(从 Bourne shell 继承的错误,已在 ksh93 中修复)。
另请注意,对于某些实现ksh
(例如旧版本的zsh
仿真ksh
),
export DirectoryName=$1
是 split+glob 调用情况。export
是类似 Korn shell 中可以评估 shell 代码的命令之一通过数组索引的算术评估), 所以就是在其中一种情况下,引用变量很重要,以避免引入命令注入漏洞。
例子:
$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux
请注意,这[ $# -gt 0 ]
是另一个 split+glob 调用,它没有意义(至少对于默认值来说不太可能成为问题$IFS
)。
答案2
您是否考虑过使用getopts
内置 shell 命令来解析您的参数(如 @Stéphane Chazelas 中的建议)这条评论)?这将为您省去很多麻烦。
在您的情况下,相关代码如下所示:
while getopts "nbd:" argname
do
case "$argname" in
n) Var1="No" ;;
b) Var2="Backup" ;;
d) DirectoryName ="$OPTARG" ;;
?) echo -e "usage is..."
exit 1 ;;
esac
done