O'Reillyの本「Unix in a nutshell」を読んでいて、次の形式を使用して、現在のシェルでコマンドをグループ化して実行できることがわかりました。
{ cmd1 ; cmd2 }
Execを呼び出すとシェルのデータが置き換えられるため、シェルはexecシステムコールから戻ることができないことを知っていたので、これがどのように可能であるか理解できませんでした。そのため、コマンドをテストしましたが、何が起こったのか理解できません。コマンドラインに入力しましたが、コマンドラインが何に属しているのかわかりません。
シェルから削除された、ターミナルエミュレータのコマンドラインだけですか?
また、現在のシェルでコマンドを実行する方法はどのように役立ちますか?
execを呼び出すとシェルのデータが置き換えられるため、シェルはexecシステムコールから戻ることができません。
ただし、すべてのコマンドが実行するプログラムの名前であるとは限りません。そのため、exec
呼び出しは関係しません。主な違いは、( cmd1; cmd2; )
とは異なり、別のシェルプロセスを取得しないことです。または、おそらくもっと正確に言えば、シェルは、シェルプロセスを実行するのではなく、子プログラムを実行するためだけに分岐します。
コマンドラインは何に属しますか。
他の答えが指摘したように、あなたの命令は不完全でした。そのため、コマンドラインはbash自体に属し、グループの終了を待っていました。
また、現在のシェルでコマンドを実行する方法はどのように役立ちますか?
最も顕著な例は、そのサブコマンドで変数を設定することです。なにこれ:
foo=1; { foo=2; echo $foo; }; ( foo=3; echo $foo; ); echo $foo
これは印刷されます
2
3
2
したがって、1つのグループ内でfoo=3
を設定しても、そのグループはサブシェルで実行され、その設定は親に伝播しませんでした。
検討する価値があるもう1つのことは、現在の作業ディレクトリです。 { cd foo; make; }
はディレクトリfoo
のままになりますが、( cd foo; make; )
はメインシェルの現在の作業ディレクトリを変更しません。
グループ化は、外部に他のコードがある場合に役立ちます。条件付き
test -f foo && { echo "Foo exists."; rm foo; }
またはリダイレクト
{ echo "Content of $PWD:"; ls; } | gzip > dirlist.gz
2行目を終了しないためです:{ cmd1; cmd2; }
は正しいです。セミコロンは「コマンドの終わり」を意味します。
help
ビルトインは、{
キーワードに対しても役立ちます。 help -m {
から:
NAME { ... } - Group commands as a unit. SYNOPSIS { COMMANDS ; }
そのため、各コマンドの後にセミコロン(;
)は必須です。