두 줄의 긴 파이프에 선호되는 구문

두 줄의 긴 파이프에 선호되는 구문

긴 파이프를 작성할 때 두 줄로 나누는 것이 더 명확한 경우가 많습니다.

이렇게 긴 명령줄은 다음과 같습니다.

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

(두 번째 줄을 들여쓸 필요는 없습니다. 파이프 자체가 이를 첫 번째 줄에 매우 명확하게 연결합니다.)

여기에는 몇 가지 이유가 있습니다.

  • 더 쉽게 볼 수 있다목수; 선의 세세한 부분까지 놓치지 않습니다. (줄이 길고 커넥터가 눈에 띄지 않게 스크롤되거나 줄바꿈으로 인해 길을 잃을 수 있는 경우 특히 중요합니다.) 코드를 빠르게 스캔하면 전체 구조가 왼쪽으로 내려다보게 됩니다. 여기서: 들여쓰기에서, 중괄호 또는 특정 언어에서 사용하는 모든 것. 파이프와 기타 연결부는 구조에 중요하므로 왼쪽에도 있어야 합니다.

  • 그것은 줄을 서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

관련 정보