キーワード、予約語、内臓語の違いは何ですか?

キーワード、予約語、内臓語の違いは何ですか?

~からBashにシェル組み込みコマンドの代わりに外部 `time`コマンドを使用させる。、Stefan Chazerasは次のように書いています。

time組み込みのbashがありません。timeキーワードなので、次のことができます。time { foo; bar; }

私達はそれを確認できます:

$ type -a time
time is a shell keyword
time is /usr/bin/time

timeこれが組み込みコマンドである可能性があることを示していません。

  1. 「キーワード」の定義は何ですか?

  2. 「キーワード」は、Bash リファレンスマニュアルの「予約語」と同じ概念ですか?

    予約語

    この単語はシェルに対して特別な意味を持ちます。ほとんどの予約語はfor、などのシェルフロー制御構造を導入しますwhile

  3. キーワードはコマンド(または組み込みコマンド)ではありませんか?

    コマンドではなくキーワードtime(または組み込みコマンドではありません)?

    キーワードと組み込み機能の定義を考えると、組み込み機能ではtime なくキーワードが必要なのはなぜですか?

  4. 「がキーワードなtime { foo; bar; }ので「できる」という理由は何ですか?time

答え1

キーワード、予約語、および組み込みコマンドは、単純なコマンドの「最初の単語」です。キーワードと組み込み関数という2つのグループに分けることができます。二人は相互に排他的です。単語(タグ)はキーワードまたは組み込みの単語ですが、両方にすることはできません。

なぜ「最初の言葉」なのか?

~から「簡易コマンド」のPOSIX定義(強調):

「単純なコマンド」は、任意の順序で任意の変数割り当ておよびリダイレクトのシーケンスであり、任意にワードおよびリダイレクトが続き、制御演算子によって終了される。

2. - 変数の割り当てや方向の再指定ではない単語を拡張する必要があります。拡張後もフィールドがまだ存在する場合最初のフィールドはコマンド名で処理する必要があります。残りのフィールドはコマンドのパラメーターです。

「最初の単語」が識別され、拡張されると(エイリアスを介して)、最後の単語は「command」になり、1行に1つのコマンドしかありません。コマンドワードは組み込みコマンドまたはキーワードです。

キーワード

はい、キーワードは「予約語」です。 「man bash」をロードしてキーワードを検索するか、次のコマンドを実行してくださいLESS=+/'keyword' man bash

検索の最初のクリックは次のとおりです。

キーワードシェル予約語。

完成した部分で発生しますが、非常に明確です。

予約語

POSIXでは「予約語」の定義少し残った予約語の役割の説明

しかし、Bashマニュアルにはより良い作業定義があります。 「予約語」(LESS=+/'RESERVED WORDS' man bash)を検索し、次を探します。

予約語予約語は、シェルに特別な意味を持つ単語です。次の単語は、引用符が付けられていない場合と、単純なコマンドの最初の単語、大文字と小文字、またはコマンドの3番目の単語の場合は予約されていると認識されます。

! case do done elif else esac fi for function if in select then until while { } time [[ ]]

組み込み

Bashのマニュアルでは定義されていませんが、非常に簡単です。

シェルの基本要件(cd、pwd、eval)を満たす、一般的な速度を満たす、または場合によっては外部ユーティリティによる解釈との競合を避けるために、シェルの内部で実装されるコマンド。

時間がキーワードです

なぜ時間は組み込みではなくキーワードなのでしょうか?

コマンドが2番目の単語として存在できるようにします。

if ... then .... fiこれは、最初のキーワードの後に​​コマンド(複合コマンドも含む)を含めることができる方法と似ていますif。またはwhileなどcase

答え2

第1四半期、第2四半期

キーワード定義

「キーワード」は、Bash リファレンスマニュアルの「予約語」と同じ概念ですか?

デフォルトでは、構文構造には特別な単語が重要です。 Cにはgoto、、ifなどがwhileあります。 bashには、(おなじみに聞こえます...)などがenumあります。ifwhiletime

はい、同じです。

POSIXシェルとbashの基本的な構文要素が似ているので、この質問を解釈するのにある程度の自由度があります。それでは、定義を見てみましょう。POSIX.1:2013 シェルコマンド言語:

2.4予約語

予約語はシェルに特別な意味を持つ単語です。シェルコマンド。次の単語は予約語と見なされるべきです。

...

この認識は、文字が引用されず、単語が次のように使用される場合にのみ発生します。

...

文法を見るシェル構文

特別な単語(これは語彙的に分析された構文トークン)がどのように機能するかを知るために、POSIX構文を見てみましょう。

for_clause       : For name linebreak                            do_group
                 | For name linebreak in          sequential_sep do_group
                 | For name linebreak in wordlist sequential_sep do_group
/* ... */
do_group         : Do compound_list Done           /* Apply rule 6 */

これはおなじみのようですね?ForDoおよびは実際にDone語彙アナライザによってマッピングされ認識されるべきトークンです。

%token  If    Then    Else    Elif    Fi    Do    Done
/*      'if'  'then'  'else'  'elif'  'fi'  'do'  'done'   */


%token  Case    Esac    While    Until    For
/*      'case'  'esac'  'while'  'until'  'for'   */

/* and 'In' too -- They made a mistake! */
%token  In    /*      'in'   */

聞いたことがあるならジャックまたはバイソン(またはjison)、それは人々が文法を使用する方法です。これらのパーサジェネレータを使用すると、特定の入力「トークン」ストリームで文法のどの部分が使用されているかを調べるものを生成できます。

第3四半期

キーワードはコマンド(または組み込みコマンド)ではありませんか?

コマンドではなくキーワードtime(または組み込みコマンドではありません)?

どのキーワードもコマンドと見なされません。ただし、もちろん、次のように同じ名前のコマンド/関数を使用できます。

# make a command to avoid command-not-found for `FOO=BAR time cmd`
time(){ time "$@"; }

キーワードと組み込み関数の定義によると、なぜ時間は組み込み関数ではなくキーワードなのでしょうか。

だからこそ人々はそれをすることにしました:

// Licensed under GPLv2, bash:parse.y
// Copyright (C) 1989-2012 Free Software Foundation, Inc.
pipeline_command: pipeline
                | BANG pipeline_command
                | timespec pipeline_command
                | timespec list_terminator
                | BANG list_terminator;
pipeline        : pipeline '|' newline_list pipeline
                | pipeline BAR_AND newline_list pipeline
                | command;
timespec        : TIME | TIME TIMEOPT | TIME TIMEOPT TIMEIGN;

彼らはそれから追加の力を得ます(次の質問を参照)。

第4四半期

「がキーワードなtime { foo; bar; }ので「できる」という理由は何ですか?time

文法の一部として、自然にパーサーがすべてを処理し、time複合コマンドの前に許可するような決定を下すことができます。timeコマンドでのみ実装されている場合は、echo { foo; bar; }実際には「一般的な」ルールを使用して解析されるため、その構文に対して構文エラー(試行)が発生します。

それについても考えてみてください[[[[キーワードでない場合は、likeを設定すると、シェルが迷子になった[[ ($a == 2) || ($b != 3) ]]括弧を見つけて文句を言います。 (交換[[して[参照してください)。

PStime便利POSIX キーワードの代わりに後者を使用することはまだ許可されていると見なされます。フルコマンドトランクはkshとbashの拡張です。

関連情報