web-dev-qa-db-ja.com

シェルスクリプトでの変数の比較

シェルスクリプトを含み、その中の値/変数を比較するプロジェクトがあります。私はここや他の場所で変数の比較について調べ、与えられたさまざまな例をすべて試しましたが、宣伝されていない何かに遭遇しています。 OSは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

一重引用符、二重引用符、および逆引用符で物を囲んでみました。

どんな助けでもありがたいです。

8
user3047191

ifの後には、他の場所と同じようにシェルコマンドが必要です。 $X = $Yはシェルコマンドとして解析されます。つまり、$Xはコマンド名として解釈されます(変数の値が単一のワードである場合)。

[コマンド(testとしても使用可能)または[[ … ]]特殊構文を使用して、2つの変数を比較できます。大括弧の内側にスペースが必要であることに注意してください。大括弧はシェル構文では別個のトークンです。

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

または

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

[ … ]はすべてのシェルで機能し、[[ … ]]はksh、bash、zshでのみ機能します。

変数を二重引用符で囲む必要があることに注意してください¹。引用符を省略すると、変数は複数の単語に分割され、各単語はワイルドカードパターンとして解釈されます。これは[[ … ]]内では発生しませんが、=の右側もワイルドカードパターンとして解釈されます。変数の置換を常に二重引用符で囲みます(変数の値を、文字列としてではなく、ファイル名一致パターンのリストとして使用したい場合を除きます)。

¹ $X[[ … ]]構文を除きます。

この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
javaPlease42