Bashスクリプト:スペースを使用する

Bashスクリプト:スペースを使用する

私はこのサイトでWeb検索と検索を試しましたが、bashの文字列にスペースを使用することに関連する問題だけが見つかりました。しかし、正しい使い方(必須事項とその逆)をよりよく覚えるために、bashスクリプトでスペースを使用する一般的なロジックを理解したいと思います。

いくつかの例:強制[ $i == b ]、反対var1="foo"

答え1

しかし、Bashスクリプトでスペースを使用する一般的なロジックを理解したいと思います。

コマンド引数とコマンドを区切るときはスペースを使用する必要があります。キーワード(またはソースに応じて予約語)。これらは{、、、、、、、、、などです。}!iffordodone

周囲のスペースは必須ではありません。オペレーター。これは少なくともステートメントターミネーター;&;すべてのリダイレクト演算子&&と括弧とです。リダイレクト演算子の前のオプションのファイル記述子番号はスペースで区切ることはできませんが、演算子の周りの余分なスペースは通常重要ではありません。||><<()

したがって、以下はすべて良いです。

true;true
cat<<file
true&&false
tac|rev
f()(echo foo)

これらは以下ではありません:

if !somecmd; then ...
f(){echo foo}

最初は、コマンドを!somecmd実行するのではなく、コマンドを検索してsomecmd終了状態を反転します。 2番目は、キーワード '{'と '{'が}別々の単語でなければならず、コマンドの先頭でのみ認識されるため、機能しません。f(){ echo foo;}例えば

ifコースをステートメントとして使用できない場合は、単語の先頭から選択すると、呼び出されifたプログラムを使用するのが難しくなります。ifconfig

ifsomecmd;then ...

(Fortranに慣れていない場合は、これは明らかです。)

それでは、これが(演算子では{なく演算子であるかどうかはどうすればわかりますか?暗記学習で学習します。これらの違いは、多くの場合と同様に、歴史的な理由による可能性があります。望むより:POSIX Shell Grammarの中括弧コマンドグループで開く中括弧の後にスペースが必要なのはなぜですか?

これらの質問に対する回答には、参照とともに演算子とキーワードに関する詳細な議論があるので、読んでください。


しかし、上記のいずれも、課題と試験foo=barの違いを区別するのに実際には役に立ちません[ "$foo" = bar ]

ここで重要なのは、[通常のコマンドと同様に、演算子とオペランドを別の引数として使用し、実際に内部を見ていないことです。ls -l /somedirectory引数(-lおよび/somedirectory)を区切るために空白が必要な場合と同様です[この括弧のペアはシェル構文の一部ではありません(または構文)とis notは、ほとんど=の実際のプログラミング言語の対応する構文とは異なります。

ミッションの場合は少しトリッキーです。割り当てはコマンドラインに単独で表示される必要はなく(コマンドで使用できます)、1行に複数の割り当てがあります。このように:

$ foobar=123 foofoo=456 env|grep foo
foofoo=456
foobar=123

おおまかに動作する方法は、シェルがコマンドを単語(上記の単語は、およびfoobar=123foofoo=456env分割し、最初の単語を調べて割り当てのように見えることを確認することです。両方とも、ここには割り当てがなく、一般的なパラメータのみがありますecho

$ echo foo=bar
foo=bar

この点でシェル構文が異なる可能性があると思いますが、2つの割り当てがあり、引数のないコマンドがある場合は、次のようなものをサポートすると奇妙に見えます(もちろんLuaに慣れていない場合)。

foobar = 123 foofoo = 456 env

答え2

鍵はスペースで区切ることです。性格、引用しない限り、性格考慮すべき事項:

デフォルトでは、シェルは次のことを行います。

  1. 入力内容をお読みください[...]
  2. 次の引用規則に従って、入力を単語と演算子に分割します。引用する。これらのタグはメタ文字で区切られます。 [...]
  3. タグを単純コマンドと複合コマンドに解析します(参照:シェルコマンド)。

-3.1.1 シェル動作

そして:

単純なコマンドは、最も一般的に使用されるコマンドです。これは単にスペースで区切られた一連の単語であり、シェルの制御演算子[.]の1つで終わります。3.2.1 簡単なコマンド

そして:

  1. パーサーが変数の割り当て(コマンド名の前の単語)とリダイレクトとしてマークした単語は、後で処理できるように保存されます。
  2. 変数の割り当てやリダイレクトではない単語は拡張されます[...]。拡張後に残りの単語がある場合、最初の単語はコマンド名として扱われ、残りの単語は引数として扱われます。

-3.7.1 簡単なコマンド拡張

「変数に割り当てるために表示された単語[...]」と言う方法に注意してください。したがって、変数の割り当ては単一の単語である必要があるため、次のようになります。ただ変数の割り当て:

  • var=value
  • var=" value"

次の場合はそうではありません。

  • var= value✗(2つの単語:変数の割り当てvar=- 空の文字列への割り当て - コマンド用value
  • var =value✗(2つの単語:varパラメータ付きコマンド=value
  • var" =value"✗(1つの単語:ただし、変数名は引用できないため、名前付きコマンドですvar =value。)
  • "var=value"✗(1つの単語:ただし、変数名は引用できないため、名前付きコマンドですvar=value。)

forは[ var = value ]テストを期待する[コマンド(と同じコマンドtest)で、テストのオペランドは次のようになります。別の主張。これにより、たとえば[ "$var" = "$value" ]or whereなどの操作を実行でき、テストのように見えますが、それぞれが単一の引数であるため、そうでないものを含めることができます。test "$var" = "$value"var="a = b"value="b = c"

パラメータは別の単語でなければならないため、周囲にスペースが必要です=。これが"$var"すぐに"$value"引用されるべき理由でもあります。それ以外の場合、シェルはそれを別の単語に分割して[失敗します。

関連情報