web-dev-qa-db-ja.com

Bash-現在のシェルでコマンドを実行する

O'Reillyの本「Unix in a nutshell」を読んでいて、次の形式を使用して、現在のシェルでコマンドをグループ化して実行できることがわかりました。

{ cmd1 ; cmd2 }

Execを呼び出すとシェルのデータが置き換えられるため、シェルはexecシステムコールから戻ることができないことを知っていたので、これがどのように可能であるか理解できませんでした。そのため、コマンドをテストしましたが、何が起こったのか理解できません。コマンドラインに入力しましたが、コマンドラインが何に属しているのかわかりません。

シェルから削除された、ターミナルエミュレータのコマンドラインだけですか?

また、現在のシェルでコマンドを実行する方法はどのように役立ちますか?

enter image description here

7
user3122885

実行するかしないか

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
5
MvG

2行目を終了しないためです:{ cmd1; cmd2; }は正しいです。セミコロンは「コマンドの終わり」を意味します。

9

helpビルトインは、{キーワードに対しても役立ちます。 help -m {から:

NAME
    { ... } - Group commands as a unit.

SYNOPSIS
    { COMMANDS ; }

そのため、各コマンドの後にセミコロン(;)は必須です。

4
Radu Rădeanu