2行の長いパイプに好ましい構文

2行の長いパイプに好ましい構文

長いパイプを作成するとき、2行に分割する方がより明確になることがよくあります。

このように長いコマンドラインは次のとおりです。

ruby -run -e httpd -- -p 5000 . 2>&1 | tee >(grep -Fq 'WEBrick::HTTPServer#start' && open localhost:5000) 

それは次のように分けることができます:

ruby -run -e httpd -- -p 5000 . 2>&1 \
   | tee >(grep -Fq 'WEBrick::HTTPServer#start' && open localhost:5000) 

または:

ruby -run -e httpd -- -p 5000 . 2>&1 |
    tee >(grep -Fq 'WEBrick::HTTPServer#start' && open localhost:5000) 

簡単に言うと:

command1 \
    | command2

または:

command1 |
    command2

私はこれがスタイル(コメント)の問題かもしれないことを知っていますが、好む方法はありますか?それでは、その理由は何ですか?

答え1

これが何をするかを自分に尋ねてください。

command1 \ 
   | command2

違いはわかりません。私もできませんが、シェルはできます。詳しく見ると、後ろにスペースがあります\。これにより、改行文字がエスケープされるのを防ぎます。

したがって、より安全な他のフォームを使用してください。ここでも同じエラーが表示されます(|この場合はスペースが後ろに表示されます)。しかし、エラーは発生しません。

command1 | 
    command2

答え2

私はここにいるほとんどの人の意見に同意しません。私はいつもパッケージを好む。今後パイプなどの接続演算子:

command1 \
| command 2

(2行目をインデントする必要はありません。パイプ自体がそれを最初の行に非常に明確に接続します。)

これにはいくつかの理由があります。

  • 見やすく大工;線の細部まで見逃せません。 (ラインが長く、コネクタが目立たないようにスクロールしたり、改行で迷子になる可能性がある場合は特に重要です。)コードをすばやくスキャンすると、構造全体が左に見えます。ここで:インデントでは、中かっこまたは特定の言語で使用されるすべて。パイプやその他の接続は構造にとって重要であるため、左側にも配置する必要があります。

  • それは並ぶ3本以上の線を超えると、今回もパイプの構造を一目でわかるようにしてくれます。

  • 私たちの考えに近づく。 (最も微妙で物議を醸す部分がまさにこれです…)もし誰かが少ないようにリストをゆっくり読んでいるなら、「[項目1]...(停止させる)…そして[項目2]…(停止させる)…そして[項目3]。 "; "[アイテム1]そして..."と言うと不自然なようです。(停止させる)… [プロジェクト2]そして…(停止させる)… [項目3]。これは、「接続者が前の項目よりも後の項目にもっと付着すると思うからです。 (演算のマイナス記号も同様の意味で考えることができます。加算のように動作しますが、否定すると次のように関連付けられます。項目の数字はより密接に関連しています)コードに私たちの考えが反映されている場合は理解しやすくなります。

私は長年にわたって複数の言語で両方のアプローチを試しました。

答え3

まあ、誰も望んでいないように見えないために:

command1 \
   | command2

そうだと言いたいです。

私はctrl-alt-delorによる末尾の空白の問題が問題だとは思わない。編集者はこれについて警告することができます。さらに、シェルは構文エラーを発生させ、| command2ユーザーに誤ったファイルと行番号を提供し、ファイルの残りの部分の解釈を停止します。

$ cat f.sh
#!/bin/bash

echo foo \ 
| command2

echo bar
$ ./f.sh
foo  
./f.sh: line 4: syntax error near unexpected token `|'
./f.sh: line 4: `| command2'

行連続エスケープがより多くの用途に使用されるという事実もあります。例えば、パラメーターの多い単純なコマンドを中断するには、次のようにします。

ffmpeg \
  -f x11grab \
  -video_size "$size" \
  -framerate "${framerate:-10}" \
  -i "${DISPLAY}${offset}" \
  -c:v ffvhuff \
  -f matroska \
  -

脱出後にスペースを追加しないと信じられないので、この使い方も避けるべきですか?

私が好むのは純粋に読みやすく、非常に主観的です。以下は私のシェル履歴の実際の例です(詳細はfoobarに置き換えられます)。

org-table-to-csv foobar.org \
| cq +H -q "
  select foo
    from t
    where bar = 'baz'
      and foo != ''" \
| sed -r 's/^|$/'\''/g' \
| sed -r ':b;$!{N;bb};s/\n/, /g'

比較:

org-table-to-csv foobar.org |
  cq +H -q "
    select foo
      from t
      where bar = 'baz'
        and foo != ''" |
  sed -r 's/^|$/'\''/g' |
  sed -r ':b;$!{N;bb};s/\n/, /g'

ここに別のものがあります:

sed 's/ .*//' <<< "$blame_out"
| sort \
| uniq \
| tee >(sed "s/^/from pipe before grep filtering: /" > /dev/tty) \
| grep -vF "$(git show -s --format=%h "$from_commit")" \
| tee >(sed "s/^/from pipe before git show: /" > /dev/tty) \
| xargs git show -s --format='%cI %h' \
| tee >(sed "s/^/from pipe after git show: /" > /dev/tty) \
| sort -k1 \
| tail -1 \
| cut -d' ' -f2

比較:

sed 's/ .*//' <<< "$blame_out"
  sort |
  uniq |
  tee >(sed "s/^/from pipe before grep filtering: /" > /dev/tty) |
  grep -vF "$(git show -s --format=%h "$from_commit")" |
  tee >(sed "s/^/from pipe before git show: /" > /dev/tty) |
  xargs git show -s --format='%cI %h' |
  tee >(sed "s/^/from pipe after git show: /" > /dev/tty) |
  sort -k1 |
  tail -1 |
  cut -d' ' -f2

答え4

私はこの質問に対する答えが簡単だと思いましたが、@JoLと@giddsは私と同意しません。

My brain prefers reading a line and not having to scan the next line \
:

  foo bar baz ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... \

In the above I will have to see \
, what is on line 2 \
, before I can tell \
, what the command does \
. Maybe the command is complete \
? Or maybe the command continues \
  on the next line \
?

To me it is much easier to read,
if \ is only used,
when a command cannot fit on a line.

私のコードを読みながらコメントが問題であることも発見しました。

foo ... ... ... ... ... ... ... ... |
    # Now this does bar
    bar ... ... ... ... ... ... ... ... ||
    # And if that fails: fubar
    fubar

orまたは前に+改行文字を使用すると、\パイプの途中でどのように説明するのかわかりません。これが不可能な場合は、これが最も重要な質問だと思います。コメントなしでコードを維持することはできません。通常、コメントはコードが変更されたときに文書の更新を促進するためにコードにできるだけ近づける必要があります。|||&&

Emacsは自動的にインデントを実行するため、インデントは追加の負担になりません。

# This is indented automatically in emacs
ruby -run -e httpd -- -p 5000 . 2>&1 |
    # Send the output to the screen and to grep
    tee >(grep -Fq 'WEBrick::HTTPServer#start' &&
              # If grep matches, open localhost:5000
              open localhost:5000) 
# Here is where emacs indents the next command to

関連情報