在shell脚本中比较变量

11

我有一个项目涉及使用shell脚本比较值/变量。我已经在这里和其他地方查找了关于比较变量的信息,并尝试了给出的所有不同示例,但是我遇到了一些问题,情况并不像广告上那样。操作系统是Solaris10。

我创建了以下脚本作为学习经验-

#!/bin/ksh

stest()
{
if $X = $Y
then echo they're the same
else echo they're notthe same
fi
}


X=a
Y=a

stest

echo completed

我一直在得到以下内容的某种变体-

使用shell sh或ksh-

#./test.sh
./test.sh[2]: a:  not found
completed

使用Shell Bash -

#./test.sh
./test.sh: line 5: a: command not found
completed

我尝试使用括号和双括号将if $X = $Y这一行括起来,但是得到的结果是

[a:  not found  
[[a:  not found

如果我将变量X和Y改为数字“1”,我得到的是相同的结果-

./test.sh[2]: 1:  not found

我尝试过用单引号、双引号和反引号来包含东西。

非常感谢任何帮助。


1
对于字符串,请尝试使用 if [ $X == $Y ]。参考链接:http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html - Jerry Jeremiah
2个回答

15

"if"后面需要一个shell命令,就像其他地方一样。"$X = $Y"作为一个shell命令被解析,意味着$X被解释为一个命令名称(前提是变量的值是单词)。

您可以使用[命令(也可用作test)或[[...]]特殊语法来比较两个变量。请注意,在括号内部需要空格:括号是shell语法中的一个独立标记。

if [ "$X" = "$Y" ]; then
或者
if [[ "$X" = "$Y" ]]; then …

[ … ] 在任何shell中都可以使用,[[ … ]] 只能在ksh、bash和zsh中使用。

请注意,在变量周围需要使用双引号¹。如果省略引号,则该变量会被拆分为多个单词,并且每个单词都将被解释为通配符模式。这在 [[ … ]] 内部不会发生,但等号的右侧也会被解释为通配符模式。除非您希望将变量的值用作文件名匹配模式列表,而不是字符串,否则始终在变量替换周围使用双引号。

¹ 除了在 $X 中使用 [[ … ]] 语法。


这个方案得到认可,适用于那些来这里寻找答案的人,我只是没有ksh来测试它。而且空格很重要。 - user10089632

4
这个KornShell(ksh)脚本应该可以工作: soExample.ksh
#!/bin/ksh 

#Initialize Variables
X="a"
Y="a"

#Function to create File with Input
#Params: 1}
stest(){
    if [ "${X}" == "${Y}" ]; then
        echo "they're the same"
    else 
        echo "they're not the same"
    fi
}

#-----------
#---Main----
#-----------
echo "Starting: ${PWD}/${0} with Input Parameters: {1: ${1} {2: ${2} {3: ${3}"
stest #function call#
echo "completed"
echo "Exiting: ${PWD}/${0}"

输出结果:

user@foo:/tmp $ ksh soExample.ksh
Starting: /tmp/soExample.ksh with Input Parameters: {1:  {2:  {3:
they're not the same
completed
Exiting: /tmp/soExample.ksh

ksh版本:

user@foo:/tmp $ echo $KSH_VERSION
@(#)MIRBSD KSH R48 2013/08/16

2
你应该在所有变量插值中使用双引号。如果 $X 包含空格,你将开始看到错误消息,或者更糟糕的是,用户输入被作为代码运行。 - tripleee
@tripleee 很好的建议,代码已更新。您有参考资料说明将所有变量插值用双引号括起来是ksh最佳实践吗? - javaPlease42
1
没有特别针对ksh的内容,但是当你知道shell如何工作时,这是相当明显的。除非你特别需要变量值的空格分割和通配符扩展,否则它需要被引用。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接