如何将带双引号的空字符串传递给bash脚本?

时间:2014-04-26 00:22:11

标签: bash shell

我正在尝试编写一个脚本,它将在命令行中接受带有双引号的空字符串作为附加参数。我希望脚本将这些参数与双引号空字符串一起传递(如果提供),但是命令解释器似乎将这样的参数解释为空字符串并删除引号。有没有办法做到这一点?

作为一个简单的例子,我将在script.sh:

文件中
#!/bin/bash
/home/myapp $1 $2

如果我在提示符下运行:

$ ./script.sh arg1 ""

脚本只执行"/home/myapp arg1",但是忽略/忽略第二个参数("")。我希望它保留这个空字符串,而不是执行:/home/myapp arg1 ""

7 个答案:

答案 0 :(得分:10)

您正在将空字符串参数正确传递给脚本。

脚本搞乱了:

#!/bin/bash
/home/myapp $1 $2

该脚本无法保护$1$2的扩展免于分词。这意味着,如果$1$2包含多个单词,则会转换为单个参数,如果其中任何一个扩展为空,它们就会消失。

这应该是:

#!/bin/bash
/home/myapp "$1" "$2"

通常,您可以让脚本将其所有参数传递给调用的程序,如下所示:

/home/myapp "$@"

引号只是shell语法;它们不是参数数据本身的一部分。当您在shell中键入program ""时,在操作系统级别,程序会收到一个空的C语言字符串:指向空字节的指针。没有引号。

您可以传递参数""(由两个双引号组成的双字符字符串),但这不是一个空参数。一种方法是,例如,'""':用单引号括起来。

执行此类操作的唯一原因是您在元级别操作shell语法:传递shell脚本源代码的部分,例如引用的标记,空或除此以外。 shell有一个名为eval的命令,它将源代码作为参数(或多个参数)并对其进行评估。

empty_shell_string_syntax='""'    # this variable holds the characters ""

eval empty_var=$empty_shell_string_syntax   # empty_var gets set to empty string

在调用eval之前,命令行可以进行扩展。该扩展会删除语法$empty_shell_string_sytnax并将其替换为内容""。因此,eval获取字符串empty_var=""。它会对此进行评估,因此empty_var将设置为空字符串,如语法所示。

答案 1 :(得分:4)

您可以通过examining the $# parameter检测您的脚本传递了多少位置参数。例如,如果这是2或更大,那么您知道$2传递了某些内容,即使$2为空(通过调用shell删除了引号)。以下实现了该逻辑,并将""传递给被调用程序(在本例中为echo),如果参数已传递但为空:

#!/bin/bash

if [ $# -ge 2 ]; then
    if [ "$2" ]; then
        arg2="$2"
    else
        arg2='""'
    fi
    echo "$1 $arg2"
elif [ $# == 1 ]; then
    echo "$1"
fi

输出:

$ ./args.sh a
a
$ ./args.sh a ""
a ""
$ ./args.sh a 1
a 1
$ 

答案 2 :(得分:3)

补充Kaz's helpful explanation
如果您通过"$@"参数也将通过

#!/bin/bash

/home/myapp "$@"

传递"$@"保留原始参数完全传入 - 甚至参数传递为空字符串(传递为,例如,''"""$someVar",其中变量someVar未设置或包含空字符串。)


如果超过2个参数

#!/bin/bash

# Copy the (up to) first 2 arguments - whether they're empty strings or not -
# to a separate array.
firstTwo=("${@:1:2}") 
shift; shift  # Remove the first 2 arguments from the arguments array.

# Invoke the app with the (up to) first 2 arguments stored in the new array.
/home/myapp "${firstTwo[@]}"

# Process the remaining arguments, if any.
for a; do
  echo "remaining: [$a]"
done

答案 3 :(得分:2)

你应该使用反斜杠

来逃避它
$ ./script.sh arg1 \"\"

可以测试,例如回声:

$ echo \"\"
""

答案 4 :(得分:2)

用反斜杠转义它们或将它们放在单引号中。

答案 5 :(得分:2)

您也可以将它们放在单引号中以获得其文字值,例如: :

  ]$ echo '""'
  ""

例如,在脚本中:

   ]# cat a.bash
     #!/bin/bash        
     echo a$1b

  ]$ ./a.sh '""'
  a""b

  ]$ ./a.sh ""
  ab

答案 6 :(得分:0)

试试这个:

va_arg