如何检查$ 1和$ 2是否为空?


40

我正在运行一些脚本,该脚本传递字符串参数,并且要执行if else语句,如下所示:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

但它显示Error too many argument。为什么?


您应该提供1.调用脚本的命令,以及2.完整的输出。
Lucio 2014年

2
您应该使用[[ ]]。否则,您必须引用变量。
Christophe De Troyer

如果$ 1不存在,则$ 2将变成$ 1,这使得对$ 1和$ 2均为空的检验似乎无关紧要。
WinEunuuchs2Unix

@ WinEunuuchs2Unix不一定无关紧要-在某些情况下,您要确保参数中确实存在某些东西,而不是空字符串或空字符串。$1可以由脚本用户取消设置或设置为null字符串。考虑以下命令顺序:$ set '' bar然后echo "x${1}x";两个变量都被设置,但是其中一个为空。
Sergiy Kolodyazhnyy

Answers:


55

尝试使用-z测试:

if [ -z "$1" ] && [ -z "$2" ]

从人bash

-z string
   True if the length of string is zero.

这个对我有用!
pengisgood

有趣的是,最投票和接受的答案没有真正回答这个问题问。
mehmet

在编写可移植的shell脚本时,应谨慎使用此标志,因为在某些商业Unix上,此标志是错误的。请参阅我的答案以获取链接源。
Sergiy Kolodyazhnyy

14

由于已对此进行了标记bash,因此我建议您使用扩展的测试构造([[...]],而忽略引号:

if [[ -z $1 && -z $2 ]]; then
...

除非您要与sh/ POSIX兼容,否则没有理由不使用[[ ]]


3

以下内容也适用

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi

&&Classic中不允许使用和其他逻辑命令分隔符test。您必须改用其他测试构造(例如-a,我认为)
muru

3

有关答案的旧版本,请参阅此答案的第二部分。如果您想了解详细信息,请继续阅读

问题原因

在问题本身中,据报道OP看到了too many arguments error,但在进行测试时bash似乎并非如此:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

随着/bin/sh这实际上被链接到/bin/dashUbuntu上,错误报告如下:

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

独立版本/bin/test还可以:

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

旁注:如果您想知道什么是什么/usr/bin/test以及为什么要使用bashand sh,那么您应该知道这[test命令的别名,它也作为独立的可执行文件或更常见地存在-作为shell内置的,这是每个shell会首先使用的东西。至于if语句,它们在命令的退出状态下操作,因此为什么[test是命令,其他所有内容都是该命令的参数-命令行参数的不正确顺序会导致错误。

返回主题:尚不清楚OP如何获得不相关的错误。但是,在所有3种情况下,问题都是相同的-未设置的变量将被视为空,因此,使用这些未引用的变量,shell看到的是

[ != '' ]

破坏了test理解的语法。还记得我所说的关于命令行参数顺序错误的说法吗?因此,为什么报价很重要。让我们启用诊断输出并查看shell执行的内容:

$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ] 
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars

测试未设置变量的更好方法

您经常看到的一种方法是:

 if [ "x$var1" == "x"  ] && [ "x$var2" == "x"  ];                                                                
 then
     echo "both variables are null"
 fi

引用吉尔斯

在[“ x $ 1” =“ x”]中,x前缀确保x“ $ 1”看起来不可能像运算符,因此shell解析此测试的唯一方法是将=视为二进制运算符。

大概应该是可移植的,因为我已经在/bin/sh脚本中看到了。它也可以像

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

当然可以使用-z标志,但是根据对某些shell的研究,特别是ksh88(根据Stephane Chazelas的说法),该标志是有缺陷的。

也可以看看


+1是一种非常有趣的方法。
WinEunuuchs2Unix

@ WinEunuuchs2Unix编辑使它变得更加有趣:)
Sergiy Kolodyazhnyy

1

我认为帖子的标题不正确,因为消息中的意图是检查$ 1和$ 2是否不为空。给定的示例只是缺少$ 1和$ 2中的双引号来工作。比较字符串时,变量必须用双引号引起来进行扩展。但是,检查$ 1和$ 2是否存在与检查$ 2是否存在相同,因为如果$ 1不存在则不存在。在这种情况下,也不需要'if'命令,因为'test'返回true / false,如果return为0 / true,则将'&&'用作'then':

[ "$2" != '' ] && commands...

使用-n(非零)更简单:

[ -n "$2" ] && commands...

要“检查$ 1和$ 2是否为空”将与检查是否没有参数相同:

[ $# -eq 0 ] && commands...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.