1. ホーム
  2. syntax

[解決済み] IFステートメントを使用しているときに、シェルコマンドを複数行に分割するにはどうすればよいですか?

2022-03-22 14:11:10

質問

シェルでコマンドを複数行に分割するにはどうすればよいですか。 if ステートメントを使用できますか?

これは有効です。

if ! fab --fabfile=.deploy/fabfile.py --forward-agent --disable-known-hosts deploy:$target; then rc=1                                                                       
fi

これはうまくいきません。

# does not work:
if ! fab --fabfile=.deploy/fabfile.py \ 
  --forward-agent \
  --disable-known-hosts deploy:$target; then   
  rc=1
fi

コマンド全体が実行されるのではなく、私が取得します。

./script.sh: line 73: --forward-agent: command not found

さらに重要なのは、今回の件と同様の問題を今後理解するために、私のBashに対する理解で足りないものは何かということです。

どのように解決するのですか?

バックスラッシュの後、改行の前に空白文字(スペースまたはタブ文字¹)がある場合、改行が失敗します。そのような空白文字がない場合、あなたの例は正常に動作します。

$ cat test.sh
if ! fab --fabfile=.deploy/fabfile.py \
   --forward-agent \
   --disable-known-hosts deploy:$target; then
     echo failed
else
     echo succeeded
fi

$ alias fab=true; . ./test.sh
succeeded
$ alias fab=false; . ./test.sh
failed

シェルにおける行末のバックスラッシュは、実は特殊なケースではなく、バックスラッシュは直後の文字を引用し、通常受けるべき特別な扱いを妨げるという一般的なルールの一例です。この場合、次の文字は改行であり、阻止される特別な扱いはコマンドの終了です。通常、引用された文字はコマンドにそのまま含まれますが、バックスラッシュされた改行文字は完全に削除されます。しかし、それ以外の仕組みは同じです。最も重要なことは、バックスラッシュは直後の文字を引用するだけで、その文字がスペースやタブであれば、文字通りのスペースやタブを取得するだけで、バックスラッシュはその後の改行には何の影響も及ぼさないことです。

Czechnology が指摘するように、¹ やキャリッジリターンも同様です。POSIX シェルは、WSL でさえも Windows フォーマットのテキストファイルとうまく付き合えません。Cygwinもそうですが、少なくとも彼らのBashポートには igncr オプションで set -o を使えば、キャリッジリターンに耐えられるようになります。