パイプとリダイレクションバインディングの優先順位は、論理和、論理積などですか?


8

演算子「;」、「&」、「&&」、または「||」の相対的なバインディング優先順位を知っています。

http://www.gnu.org/software/bash/manual/bashref.html#Lists

しかし、パイプが「&&」と一緒に画面に入ってくると、結合の強さを理解するのに苦労し、正しいコマンドに出くわすか、あきらめます。

'|'のバインディングの優先順位とは 上記と比較して「>」ですか?

私が混乱する例:

ls _thumbnails/video.mp4.jpg 2>/dev/null 
    && echo "thumbnail already generated. Not regenerating" \
    && exit \
    || ffmpeg_thumbnail_create video.mp4 2>/dev/null \
    && ls _thumbnails/video.mp4.jpg \
    && echo "Thumbnail successfully created" \
    && exit \
    || echo "Thumbnail creation failed" \
    | tee ~/thumbnails.log

上記の目的は、サムネイルがまだない場合にのみサムネイルを作成することです(私は毎日cronjobを実行しています)。そして、エラーがない場合(Unixの方法ではない)のffmpegの大量の出力は好きではありません。他の状況もあるので、これらのプログラムに固有の個別のステートメントまたは特別なオプションを使用するアドバイスを私に与えないでください。バインディングの優先順位を理解したい。


非常に参考になりました-返答の場合は、これを正しいとマークします。もう1つ質問があります。優先順位を変更するにはどうすればよいですか?理論的には私は{... }うまくいくはずだと思います。私は体系的にそれを試みなかったかもしれません、そして、期待された結果を得ませんでした。
Sridhar Sarnobat 2014年

回答:


12

短い答えはつまり<>およびその変異体は、続いて(結合最も緊密)最も高い結合の優先順位を持って|、続く&&||続く、;&。したがって、echo "Thumbnail creation failed"パイプされるのはだけteeです。

やや長い答えは、最高の優先順位が実際にはグループ化であることを示し、括弧または中括弧で示すことができます。例えば、

A  &&  (B; C)

そして

A  &&  { B; C;}

にほぼ等しい

if A
then
    B
    C
fi

ノート:

  • 括弧はサブシェルを提供します。つまり、コマンドBC子プロセスで実行されます。したがって、変数の割り当てなどのコマンドcd は、親シェルには影響しません。中括弧で囲まれたAコマンドは、コマンドと同じプロセスで実行されます。したがって、ブレース構築物はA && { B; C;}近いですif- then- else構築物。
  • ブレース構文では、の後にスペースがあり、の前に(または、または改行)が必要です。{;&}

詳細については、「シェルの制御およびリダイレクト演算子とは」を参照してくださいまた、「必要な場合」はいつ必要ですか?(特に私の答え)。

以下のためにも、より一層読み、参照はbash(1)のマニュアルページ、シェルコマンド言語のPOSIX仕様/定義具体的には、2.9節、シェルコマンド およびセクション2.10.2、シェルの文法規則を。これは、上記のコンテキストを提供する試みです。

  • のようなもの

    • myVar=42
    • IFS= read a
    • date
    • cd /some/directory
    • ls -laR dir1 dir2
    • cat foo* > /tmp/allfoo
    • ls -laR dir{1,2}
    • find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
    • > newfile
    • [ -f catfood ]
    • exit

    すべてが「単純なコマンド」と見なされます。

  • のようなもの
      simple_command 1   |   simple_command 2   |   simple_command 3
    「パイプライン」です。文法は、このような正式な文法(およびCのようなプログラミング言語)で一般的であるように、ビルディングブロックを確立して構築します。そのため、個々の「単純なコマンド」は含まれていませんが、「パイプライン」と見なされますパイプ。変数の割り当てがパイプラインのコンポーネントであることは(セマンティック)意味がありませんが、x=1 | od -abまたはのようなls -laR | z=0構文は有効です。
  • のようなもの
      パイプライン1   &&   パイプライン2   ||   パイプライン3
      bashでは「リスト」と呼ばれ、POSIXでは「AND-ORリスト」と呼ばれます。ここでも、個々の「パイプライン」または個々の「単純なコマンド」は、ANDまたはORが含まれていなくても、「AND-ORリスト」と見なされます。
    • あなたがのようなものになるとき
        AND-ORリスト1   AND-ORリスト2  ;   AND-ORリスト3
        命名法は少し矛盾し始めます。Bashはこれらの「リスト」も呼び出します。POSIXでは、これらを「リスト」、「複合リスト」、および(まれに)「用語」と呼んでいます。繰り返しますが、個々の「AND-ORリスト」、「パイプライン」、または個々の「単純なコマンド」でさえ、a &またはa が含まれていなくても、「リスト」と見なされます;
      • のようなもの
          compound_list 
          そして
            {  compound_list ;}
            フロー制御コマンドfor(  ifthen- - else、  whileなど)「化合物コマンド」と呼ばれます。 
          • 上記の例では、、、およびを解釈しA、パイプラインであることがおそらく最も理にかなっています。「パイプライン」は個々の「単純なコマンド」になる可能性があることを覚えておいてください。パイプを含める必要はありません。BC


            1
            役割について詳細に説明してくれてありがとう(... ){... }。以前の悪い経験から、関連性に関する限り、角括弧は「動的コマンド」(つまり$(.. ))のコンテキストでのみ使用されると結論付けていました。
            Sridhar Sarnobat 2014年
            弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
            Licensed under cc by-sa 3.0 with attribution required.