2017-12-11 9 views
0
cat > variables.sh << EOF1 
#!/bin/bash 
echo "Please enter your first name:" 
read -e -i "Bob" FIRST_NAME 
echo "Please enter your last name:" 
read -e -i "Marley" LAST_NAME 

echo "First name: $FIRST_NAME" 
echo "Last name: $LAST_NAME" 
if [[ "$FIRST_NAME" == "Bob" ]] ; then 
echo "Last name: $LAST_NAME" 
fi 
EOF1 
source ./variables.sh 

に上記の結果を実行:何らかの理由でなぜif文の中でBash変数を空にしますが、if文の外側ではないのはなぜですか?

First name: Bob 
Last name: Marley 
Last name: 

、if文の内部LAST_NAME変数が空​​です。しかし、スクリプトが実行された後、私は

echo "Last name: $LAST_NAME" 

手動で呼び出した場合、私は、次を参照してください。

Last name: Marley 

だから、私は変数が実際に最後の名前が含まれています知っています。

if文のコンテキストがif文の外部のコンテキストと異なるかのように動作しています。それは正確ですか?

私が期待しているようにこの作業を行うにはどうすればよいですか(ifステートメントの中の$ LAST_NAMEには姓が含まれています)。

私はこれをRHEL7でテストしています。このよう

答えて

3

使用here-doc

cat > variables.sh <<-'EOF1' 
#!/bin/bash 
echo "Please enter your first name:" 
read -e -i "Bob" FIRST_NAME 
echo "Please enter your last name:" 
read -e -i "Marley" LAST_NAME 

echo "First name: $FIRST_NAME" 
echo "Last name: $LAST_NAME" 
if [[ "$FIRST_NAME" == "Bob" ]] ; then 
echo "Last name: $LAST_NAME" 
fi 
EOF1 

現在のシェルで$変数の拡大を防ぐことができますEOF1に引用符を使用します。

いいえパラメータと変数の展開、コマンド置換、算術式展開、またはパス名展開をワードに対して実行される:man bashあたりよう

。 単語の一部がの場合はとなりますが、区切り記号はwordの引用符で囲まれた結果であり、here-documentの行は展開されません。 wordが引用符で囲まれていない場合、here-documentのすべての行は、パラメータ展開、コマンド置換、および数値展開の対象となります。文字列\は無視され、文字は\,$および`を引用するために\を使用する必要があります。

2

私はあなたのスクリプトを試したときに、第1エコー・ステートメントがあなたのために働いた理由と第2エコー・ステートメントがなぜ私のために失敗したのか分かりません。しかし、若干の変更を加えれば、問題を解決できます。

anubhavaで述べたように、変数の値は即座に実行され、宛先スクリプトに渡されません。あなたはバックスラッシュでそれらをエスケープする必要があります。また、if文で[[と]]を使用する必要はありません。また、if文では、等号(=)が1つだけ使用されます。

ご希望のvariables.shスクリプトは、このようにしたいのであれば:

#!/bin/bash 
echo -n "Please enter your first name: " 
read -e -i "Bob" FIRST_NAME 
echo -n "Please enter your last name: " 
read -e -i "Marley" LAST_NAME 

echo "First name: $FIRST_NAME" 
echo "Last name: $LAST_NAME" 
if [ "$FIRST_NAME" = "Bob" ]; then 
    echo "Last name: $LAST_NAME" 
fi 

あなたが最初のスクリプトは、この行う必要があります。

cat > variables.sh << EOF1 
#!/bin/bash 
echo -n "Please enter your first name: " 
read -e -i "Bob" FIRST_NAME 
echo -n "Please enter your last name: " 
read -e -i "Marley" LAST_NAME 

echo "First name: \$FIRST_NAME" 
echo "Last name: \$LAST_NAME" 
if [ "\$FIRST_NAME" = "Bob" ]; then 
    echo "Last name: \$LAST_NAME" 
fi 
EOF1 
source ./variables.sh 

そして、それはあなたの問題を解決する必要があります。ここに私の出力です:

Please enter your first name: Bob 
Please enter your last name: Marley 
First name: Bob 
Last name: Marley 
Last name: Marley 

注:私はまた、あなたのecho文の末尾に「-n」オプションと引用符内のスペースを追加しました。これは改行を抑制し、プロンプトと同じ行に答えを入力できるようにします。

+0

移植性に関心がないなら、 '[]'を使うことによる実質的な利点はありません。 '[[]]'キーワードは高速であり、 '[]'は多くの関数を持っています。 – PesaThe

+0

一方、 'echo -n'は' bash'がコンパイルされたオプションに依存することがあるので、本当に*移植性がありません。代わりに 'printf'を使うか、この場合' read -p 'と入力してください: "..."。 –

+0

私は同意します。私は 'echo -n'オプションがOSフレーバーによっては常に移植可能ではないことを知っていました。しかし、それはしばしば利用可能です - 私は多くの場合にプロンプ​​トをクリーンアップする簡単な方法を示していました。 'read -p'オプションも常に利用可能なわけではありません。 – ByteSlinger

関連する問題