“for”와 같은 줄에“do”를 배치해야하는 이유는 무엇입니까?


28

1. 요약

이해가 안되는데E010 bashate rule이 필요한 가요 ?


2. 세부 사항

린트 파일 에는 bashate 를 사용 .sh합니다. E010 규칙 :

이렇게 같은 줄에하지 에 대한

for bashate :

  • 옳은:

    #!/bin/bash
    for f in bash/*.sh; do
        sashacommand "$f"
    done
  • 오류:

    #!/bin/bash
    for f in bash/*.sh
        do sashacommand "$f"
    done

유효한 논쟁이 필요한 이유는 무엇 for이며 do같은 줄에 있습니까?


3. 유용하지 않다

내 질문에 대한 답변을 찾을 수 없습니다 :

  1. 구글
  2. 최상의 코딩 방법에 관한 기사 ( )
  3. bashate 문서 . 나는 단지 찾는다:

    제어 블록에서 일관된 상태를 유지하는 데 도움이되는 일련의 규칙. 롤링은 "흥미로운"종류이기 때문에 계속되는 긴 줄에서는 무시됩니다.


3
들여 쓰기 do는 분명히 조금 이례적이지만 for ... \ndo\n<indent>body...매우 일반적이며 더 이상을 추정 for ... ; do합니다. 또한 그것에 대해 불평합니까?
마이클 호머

20
bashateA는 스타일 검사기. 스타일은 본질적으로 주관적입니다. 부과하는 artibrary 스타일이 마음에 들지 않으면 사용하지 마십시오. 대신 shellcheck 와 같은 구문 / 버그 검사기를 고려해야합니다 .
meuh

@ meuh, 고맙습니다. 저는 이미 ShellCheck를 사용하고 있습니다. 내 질문 : E010- 유일한 스타일 규칙 또는 내가 필요로하는 경우에 대한 그리고 뿐만 아니라 스타일의 이유로 같은 줄에.
Саша Черных

10
이 할 수있는 구문 의무 결코 없다 위해 그리고 셸에서 같은 줄에가.
meuh

1
@ Саша Черных 그것은 그 자체로 들여 쓰기가 아니며, 들여 쓰기가 아닙니다 do. 그것은의 여는 중괄호 들여 쓰기처럼 if파이썬이 그것을 허용하는 경우, 퍼팅 것,와 C 같은 언어의 또 다른 예에서와 같은 줄에 코드를 추가 :if다음 줄에 들여 쓰기를하고 같은 줄에 코드를 추가. 그것은 신체의 추가 라인과 다르게 만들 것입니다.
JoL

답변:


60

문법적으로, 다음 두 코드 스 니펫은 정확하고 동등합니다.

for f in bash/*.sh; do
    sashacommand "$f"
done
for f in bash/*.sh
    do sashacommand "$f"
done

후자는 수있는 가능성 으로 읽기 어렵게라고 할 do약간 루프 본체에서 명령을 난독. 루프에 여러 명령이 포함되어 있고 다음 명령이 새 행에 있으면 난독 화가 더 강조 표시됩니다.

for f in *
    do cmd1
    cmd2
done

...하지만 "오류"로 표시하는 것은 객관적인 진실보다는 누군가의 개인적인 의견입니다.

일반적으로 거의 모든 ;것이 개행으로 대체 될 수 있습니다. 모두 ;와 줄 바꿈 명령 터미네이터이다. do"이 for루프 에서 수행해야 할 사항을 따릅니다"라는 의미의 키워드입니다 .

for f in *; do ...; done

와 같다

for f in *
do
   ...
done

그리고

for f in *; do
   ...
done

서로를 사용하는 이유는 가독성과 지역 / 개인 스타일 규칙 때문입니다.


개인적인 의견 :

매우 긴 루프 헤더에서는 다음 do과 같이 새 줄을 작성하는 것이 합리적이라고 생각합니다 .

for i in animals people houses thoughts basketballs bees
do
    ...
done

또는

for i in        \
    animals     \
    people      \
    houses      \
    thoughts    \
    basketballs \
    bees
do
    ...
done

성명서 then에서도 마찬가지 if입니다.

그러나 이것은 다시 개인 스타일 선호도 또는 팀 / 프로젝트가 사용하는 코딩 스타일에 달려 있습니다.


“매우 긴 루프 헤더에서는 줄 바꾸기를하는 것이 합리적 일 수 있습니다.”라고 말합니다. 그 이유를 알려 주시겠습니까? 헤더 뒤에가 있어야 한다는 점을 감안할 때 do다음 줄에 넣는 것이 가독성에 도움이되는 이유는 없습니다.
Konrad Rudolph

3
@KonradRudolph 터미널의 너비는 80 자입니다. 목록 랩 경우, 나는 경우, (내 마지막 예에서와 같이) 그것을 continuated 라인의 세트를 만들 것입니다 거의 랩, 나는 둘 것이다 do(또는 then(마지막 두 번째의 예에서와 같이) 그 자체로 한 줄에)입니다. 이 모든 것은 개인적인 취향과 관련이 있습니다. 터미널 길이가 80 글자 "단지"이기 때문에 지나치게 긴 줄을 좋아하지 않으며, 부분적으로 어수선 해 보이기 때문에 생각하기도합니다. 또한 오류에 대해 매우 긴 줄을 구문 분석하는 것이 어렵다는 것을 알았습니다.
Kusalananda

1
이것이 의견이라고 계속 지적 할 필요는없는 것 같습니다. bashate는 스타일 가이드이므로 본질적으로 의견을 기반으로합니다.
Barmar

4
@Barmar, 여기의 질문은 "need to"와 "rule"과 같은 구절을 사용하고 bashate readme do는 별도의 줄에 "error"를 갖습니다 . 이 때문에 사람들은 오히려 엄격한 문구입니다 않습니다 꽤 반대로, 소위 "규칙"실제로 단지 주관적인 의견이며, 지적 가치를 보인다.
ilkkachu

2
@mtraceur 맞습니다. 저는 개인 취향에 의문을 제기하지 않습니다. 그러나 인용 한 가독성 열 제한은 코드에 적용되지 않습니다. 산문에만 적용됩니다. 안구 운동은 코드 판독에서 근본적으로 다르므로 해당 연구의 증거는 여기에 적용되지 않습니다. 더 이상 이론적 근거로 적용되지 않는 역사적 이유를 사용하는 경우에도 8.3 파일 이름을 사용했습니다.
Konrad Rudolph

28

페이지 상단에 표시된 내용을 참고하십시오.

bashate : bash 스크립트와 동등한 pep8

PEP8 은 Python 코드 용 스타일 가이드입니다. 파이썬 사람들은 종종 자신의 스타일 문제를 매우 진지하게 생각하는 것처럼 보이지만 [인용이 필요합니다] , 그것은 단지 가이드 일뿐입니다. 우리는와 do같은 줄 for에 넣는 것과 그것의 줄에 넣는 것에 대해 거꾸로 할 수있었습니다 .

또는 블록 (또는 그와 같은)을 {시작할 때 C 코드 를 어디에 넣을 것인지와 같은 토론 입니다.ifwhile


문서의 아래 몇 줄에는 또 다른 흥미로운 규칙이 있습니다.

E020 : 함수 선언이 형식이 아님 ^function name {$

여기서 중요한 점은 해당 스타일 가이드의 저자가 function독자가 함수 선언을 인식하기 위해 키워드를 사용해야 한다고 생각한다고 가정합니다 . 그러나, function fooA는 비 - 표준 기능을 정의하는 방법은 다음 표준 방법이다 foo(). 두 가지 (Bash)의 유일한 차이점은 /bin/shDebian 또는 Ubuntu 와 같이 다른 하나는 표준 쉘로 포팅하기가 어렵다는 것 입니다.

그래서, 나는 모든 스타일 가이드를 소금 또는 3 알갱이로 가져 와서 최고의 스타일이 무엇인지 스스로 결정하는 것이 좋습니다. 좋은 스타일 검사기를 사용하면 일부 검사를 비활성화 할 수 있습니다 (수신자가 bashate -i E010,E011두 가지 검사를 무시해야 함). 우수한 스타일 검사기는 예를 들어 E020의 반대를 확인하는 등 테스트를 수정할 수 있습니다.


12

TL; DR : 필요하지 않습니다. 그냥 친구의 의견 일뿐입니다.

다른 많은 사람들처럼, 나는 for수십 년 동안 이와 같은 루프를 작성해 왔습니다.

for F in arg1 arg2 arg*
do
    somecommand "$F"
done

이 레이아웃 do ... done은 C와 같은 언어의 중괄호와 같이 루프 본문 을 둘러싼 사실을 강조하고 개행을 통해 루프 구성 요소를 분리 할 수 ​​있습니다.

물론 중괄호를 어디에 배치해야하는지에 대한 종교적인 전쟁이 있기 때문에 배심원 단이 아직이 중 하나라고 말할 수도 있습니다. IMHO, 이것이 분명히 작동하도록 설계된 방식입니다. Bourne은 일치하는 구분 기호를 좋아했습니다. if ... fi,, case ... esac짧은 버전의 세미콜론이 필요하다는 것은 원래 설계된 것보다 더 짧게 만들고 있음을 나타냅니다. 아무 문제가 없습니다. 기술 발전과 한때 좋은 생각처럼 보였던 많은 것들이 이제는 눈살을 찌푸리고 goto있습니다. 그러나 전체 쉘 스크립팅 커뮤니티가 bashate저자 의 선호를 채택 할 때까지는 별도의 조치를 취할 필요가 없습니다.


3
fi에 해당 if하고, esac등 알골 68 유일한 이유에서 비롯 for루프의 do에 의해 종료되지 않는 odod기존의 표준 유틸리티의 이름입니다. 참조 en.wikipedia.org/wiki/ALGOL_68C#Algol_68C_and_Unix
Kusalananda

1
오른쪽과 키워드로 구분 된 블록은 Pascal ( begin ... end등 을 사용하는 등)을 포함하여 Algol 패밀리의 다른 언어에서도 사용되었습니다 .
Alexis

2
에 관한 이야기를 듣지 못했습니다. od우스운 일입니다. (그러나, 왜 for 루프를 끝내지 rof않겠습니까?)
alexis

2
@alexis 글쎄, Kusalananda가 말했듯이 Algol 68에서 나온 것이 핵심입니다. 원래 Bourne 쉘의 제작자 인 Stephen Bourne은 그 언어의 영향을 많이 받았기 때문에 그 구문을 고수했습니다. 그가 C로 글을 쓸 때조차도 bourne shell의 소스 코드를 참조하십시오 : minnie.tuhs.org//cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h Oh, and by by 방법 BEGINEND거기에 정의되어 있습니다.
Sergiy Kolodyazhnyy

1
이 전체 서식 스타일은 Algol 68에서도 나옵니다. 그 FORDO또한 전체 루프가 쉽게 한 줄에 딱 맞는 경우를 제외하고는 규칙에 의해 별도의 라인에있을 것이다.
reinierpost

3

아무도이 유효하고 이식 가능한 구문을 아직 언급하지 않은 것에 놀랐습니다.

set alfa bravo charlie
for q do
  echo "$q"
done

조심스럽게 주목 그 fordo세미콜론없이, 같은 줄에 있습니다. 결과:

alfa
bravo
charlie

나는이 모호한 (그러나 어떤 경우에는 깨끗하고 이식 가능한 쉘 코드에 중요) 구문에 대한 언급을 꽂는 것에 대한이 답변을 승인하지만, 이것이 위치 매개 변수를 방해한다고 사람들에게 명시 적으로 설명 할 가치가 있으며, 유일한 "(TM) 진정한 휴대용는"형태는 하나입니다 for qdo(이 예에서는 양식이 원래 Almquish 쉘 (에 지원하지 않는 커플 수십 년 전 별도의 라인에있는 ash) : in-ulm.de/~mascheck/various/ bourne_args / # endnote )
mtraceur

이 답변의 예제는 저에게 효과적이지만 OP의 질문에 예제에 적용하는 것은 효과 가 없습니다 .
Scribblemacher

3

여기에 몇 가지 좋은 답변이 있습니다. 항상 소금 한 알과 함께 스타일 가이드를 가져오고 IMHO와 경험은 스타일에 관해서 과도한 교리가있는 지역 사회에 대해 항상 약간 걱정해야합니다. 마치 내가 마지막으로 점을 찍었을 때 마지막 T가 넘어지면 소프트웨어가 작동한다고 믿는 것과 거의 같습니다. 때로는 버그를 제거하는 데 완벽한 스타일 이상의 것이 필요합니다 ...

쉘을 배우기 시작할 때 대부분의 스크립트와 튜 트는 인라인 세미콜론 형식을 사용했습니다.

for i in "$@"; do
    stuff
done

그러나 나는 경험이 없었기 때문에 조금 힘든 시간을 보냈습니다. 그리고 구문 정확성을 확인하는 데 필수적입니다. 그래서 나는 다음 줄에서 그 일을 스스로 선호했습니다. 더 이상 그렇게하지 않습니다

또한 'while'명령은 멋진 작은 트릭을위한 훌륭한 후보입니다.

while prep1; prep2; condition; do
    stuff
done

그러나 prep 명령이 약간 부피가 크거나 조건이 복잡한 경우 다음과 같이 형식화하는 것이 좋습니다.

while
    prep1
    prep2
    condition
do
    stuff
done

그런 다음 do를 "; do"로 추가하는 것은 긍정적입니다.

그보다 더 강렬해질 수도 있습니다.

while
    if con1; then
      cond2
    elif cond3; then
      cond4
    elif cond5; then
      cond6
    else
      cond7
    fi
do
    stuff
done

모든 진술은 표현이기 때문입니다. 두 스타일이 어떻게 기회 적으로 사용되는지 주목하십시오. 깨끗하게 유지하고 읽을 수 있습니다. 스타일이나 "공간 절약"이라는 이름으로 압축하거나 뒤 틀리면 끔찍한 혼란이됩니다.

그래서! 일반적으로 쉘 스크립트의 바로크 스타일을 고려할 때 선명도를 높이고 중요한 기호에 쉽게 시각적으로 액세스하는 것을 목표로하는 것은 항상 좋은 것입니다.

'do'가 명령과 함께 인라인으로 작성된 형식은 약간의 명령이있을 때 달콤합니다 .'do '가 시각적으로 숨겨져 있거나 내부 명령이 실제로 모호하지 않습니다.

for i in whatever
  do stuff
done

나는 그것을 보는 것이 매우 즐겁다는 것을 알았습니다.

while condition
  do stuff
end

if condition
  then stuff1
  else stuff2
fi

case $blah in
  a) stuff1;;
  b) stuff2;;
  c) stuff3;;
  *) stuffInfinity;;
esac

명쾌하고 일반적인 정직함은 Codd *가 요구하는 모든 것입니다.

* 관계형 데이터베이스 이론의 아버지 인 Edgar F. Codd


1
을 본 적이 while으로 if이전 상태. 시원한!
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.