将带有空格的选项/参数/参数从脚本传递到其中的函数

将带有空格的选项/参数/参数从脚本传递到其中的函数

大家好,提前致谢。

我在论坛上搜索了我的情况,但无法找到解决方案。我有一个在命令行传递参数/选项/参数的脚本。其中一个值中有一个空格,我将其放在双引号中。提供一个例子可能会更容易。请原谅我对参数/选项/参数的使用。

$:  ./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

相关内容