長いパイプを作成するとき、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