最近、シェルを使用して、f サーバー プログラムをバックアップおよび置き換えるスクリプト replace.sh を作成しました。本来の目的は、人的資源と反復的な機械的労力を節約することでした。脚本作成の過程で、不注意により余分なスペースが入ってしまい、予期せぬ事態が発生してしまいました。
1. まず問題のある replace.sh を見てみましょう
リスト 1: replace.sh
1 #!/bin/sh 2 file="mv.sh" #日志清理脚本 3 bak="mv" 4 replace="scp" 5 hostPath="/data/kuyin_new/musicsearch/bin/logs" 6 #hostList=(172.16.72.50 172.16.72.56 172.16.72.58 172.16.72.76 172.16.72.78 172.16.72.96 172.16.72.98) 7 hostList=(172.16.72.50) 8 for host in ${hostList[*]} 9 do10 bakCmd= "ssh $host $bak ${hostPath}/$file ${hostPath}/${file}.bak" #先备份目标机器上的脚本,这里=之后多打了一个空格11 echo $bakCmd #这里先打印一下bakCmd命令,看一下12 #bash -c "$bakCmd"13 #replaceCmd="$replace $file ${host}:${hostPath}" #拷贝至目标机器14 #finalCmd="${bakCmd} ; ${replaceCmd}"15 #echo $replaceCmd16 #echo $finalCmd17 #bash -c "$finalCmd"18 done
スクリプトを実行すると、結果は次のようになります:
スペース、次に bash replace.sh がスクリプトを実行すると、予期しない状況が発生します: ssh 172.16.72.50 mv /data/kuyin_new/musicsearch/bin/logs/mv.sh /data/kuyin_new/musicsearch/bin/logs/mv。 sh.bak ( ssh $host $bak ${hostPath}/$file ${hostPath}/${file}.bak変数置換後の結果) 実際にコマンドが実行されました! 私の本来の目的は、コマンドの組み合わせが正しいかどうかを確認するためにechoを使用することですが、このコマンドは実行されません。では、なぜこのようなことが起こるのでしょうか?
問題を調べるには、bash -x replace.sh を通じてスクリプトを実行できます。 「-x」オプションを使用すると、シェルはスクリプトの実行中に実際に実行する各コマンドラインを表示し、行の先頭に「+」記号を表示します。 「+」記号の後に表示されるのは、変数置換後のコマンド ラインの内容であり、実際にどのようなコマンドが実行されたかを分析するのに役立ちます。 「-x」オプションはシンプルで使いやすく、ほとんどのシェル デバッグ タスクを簡単に処理できます。これをデバッグの最初の選択肢として考慮してください。 bash -x replace.shを実行すると、結果は以下の通りです:
replace.shの10行目は2つのコマンド(黄色のボックスと赤のボックスの合計)に分割されていることがわかります。 2コマンド)なので、
ssh $host $bak ${hostPath}/$file ${hostPath}/${file}.bakが実行されます。次に、10 行目の余分なスペースを削除して、その効果を確認します。 2. 通常の replace.sh
リスト 2: replace.sh
1 #!/bin/sh 2 file="mv.sh" #日志清理脚本 3 bak="mv" 4 replace="scp" 5 hostPath="/data/kuyin_new/musicsearch/bin/logs" 6 #hostList=(172.16.72.50 172.16.72.56 172.16.72.58 172.16.72.76 172.16.72.78 172.16.72.96 172.16.72.98) 7 hostList=(172.16.72.50) 8 for host in ${hostList[*]} 9 do10 bakCmd="ssh $host $bak ${hostPath}/$file ${hostPath}/${file}.bak" ##先备份目标机器上的脚本,去除了多余的空格,此时第10行就是一个命令11 echo $bakCmd12 #bash -c "$bakCmd"13 #replaceCmd="$replace $file ${host}:${hostPath}" #拷贝至目标机器14 #finalCmd="${bakCmd} ; ${replaceCmd}"15 #echo $replaceCmd16 #echo $finalCmd17 #bash -c "$finalCmd"18 done
実行結果は次のとおりです:
したがって、シェル スクリプトを記述するときは、スペースに特に注意してください。
以上がスペースによって引き起こされるシェル例外の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。