콜론 내장은 어떤 목적으로 사용됩니까?


44

나는 많은 쉘 스크립트를 해킹했으며 때로는 가장 간단한 것들이 나를 방해합니다. 오늘 나는 :(콜론) bash 내장을 광범위하게 사용하는 스크립트를 보았습니다.

documenation는 충분히 간단한 것 같습니다 :

: (a colon)  
     : [arguments]  

인수를 확장하고 리디렉션을 수행하는 것 외에는 아무것도하지 마십시오. 반환 상태는 0입니다.

그러나 이전에는 셸 확장 시연에서만 사용되었습니다. 내가 본 스크립트의 유스 케이스는이 구조를 광범위하게 사용했습니다.

if [ -f ${file} ]; then
    grep some_string ${file} >> otherfile || :
    grep other_string ${file} >> otherfile || :
fi

실제로 수백 개의 greps가 있었지만, 그들은 거의 동일합니다. 위의 간단한 구조 이외의 입력 / 출력 리디렉션이 없습니다. 나중에 스크립트에서 반환 값을 확인하지 않습니다.

나는 이것을 "또는 아무것도하지 않는다"는 쓸모없는 구조로 읽고 있습니다. 이 grep를 "아무것도하지 않고"끝내는 목적은 무엇입니까? 어떤 경우에이 구조가 단순히 || :모든 사례에서 벗어나는 것과 다른 결과를 초래 합니까?


10
내가 볼 수있는 한 가지 가능한 목적은에 :대한 대안으로 사용 하는 것 true입니다. 아마도 errexit설정되어 있고 작성자는 일부 명령의 종료 상태를 신경 쓰지 않습니다.
jw013


Stackoverflow 링크 페이지는 좀 더 포괄적 인 IMO입니다 (이 페이지와 링크 된 페이지를 모두 읽는 것이 좋습니다).
Trevor Boyd Smith

답변:


29

나타납니다 :스크립트에들 대신에 이용되고있다 true. 경우 grep파일에 일치하는 항목을 찾을 수없는, 0이 아닌 종료 코드를 반환합니다; jw013이 주석에서 언급했듯이 errexit, 아마도 -eshebang 행에 의해 설정되면 greps 중 하나 가 일치하는 것을 찾지 못하면 스크립트가 종료됩니다 . 분명히, 그것은 저자가 원하는 것이 아니기 때문에 || :, 더 일반적인 (내 경험에서) || true/ 와 같이 특정 복합 명령의 종료 상태를 항상 0으로 만들기 위해 추가 했습니다 || /bin/true.


어. 이것은 RPM 빌드 스크립트의 개념에 있었고 스크립트 내부에서 종료 코드 검사를 보지 못했지만 부모 프로세스 가보고 있다는 것을 잊어 버렸습니다.
Caleb

8
그럴 경우, 나는 그것을 나쁜 스크립팅 연습이라고 부를 것입니다. true대신 기능을 사용 하는 것과 동일 하지만 의미 적 의도는로 더 명확합니다 true. :명시적인 NOP가 필요할 때 더 적합합니다.
jw013

내 경험상, 이것은 RPM 스크립트에서 일반적인 관행입니다. 아마 아닐 것입니다, 그러나 우리가 있습니다.
mattdm

일부 지지자가 선호하는 :대신 true때문 :이다 bash내장 등의 경우 true일반적으로 더 많은 오버 헤드와 컴파일 된 바이너리입니다. 일반적으로 true코드가 더 읽기 쉽기 때문에 사용 합니다 (마찬가지로 source대신 사용하는 것이 좋습니다 .).
Trevor Boyd Smith

36

:내장도 확장은 종종 부작용으로 만 사용되며 확장 값이 떨어져 발생합니다 배쉬 "할당 기본값"쉘 확장에 유용합니다 :

# assign FOO=bar iff FOO is unset
: ${FOO:=bar}

2
이것을 찾고 여기에 왔는데, 기본값을 선언하기 위해 스크립트 에서이 패턴을 보았을 때 당황했습니다.
ffledgling

20

:과거에 사용한 두 곳을 생각할 수 있습니다 .

while :
do
     shell commands
     some exit condition
done

그것은 영원한 고리입니다.

function doSomethingStub {
    :
}

최고 수준의 제어 흐름을 올바르게 얻기 위해 스텁 기능을 사용하십시오.

내가 옛날에 보았던 한 가지 용도 : #!/bin/sh(또는 무엇이든) 선 대신에 :선이 나타납니다. 구형 Real Unix 커널 또는 Real Unix 쉘 중 일부는이를 사용하여 "저는 쉘 스크립트입니다. 내가 기억하는 것처럼 이것은 csh가 일반적인 대화식 쉘로 진입했을 때였습니다.


@BruceEdiger : "shecolon"라인에 대한 참조가 있습니까?
l0b0

7
마지막으로 ":: 스크립트 시작 부분에"참조 및 설명 : faqs.org/faqs/unix-faq/faq/part3/section-16.html
Bruce Ediger

1
처음부터의 행동 :은 매우 이상합니다. 스크립트가 실제로 실행되는 것을 발견했습니다 sh. shebang없이 스크립트를 시작할 때 ... 쉘이 실행중인 스크립트를 실행하려고 시도합니다 (따라서 실행중인 bash것처럼 bash마치 csh실행하려고 시도합니다 csh).
Trevor Boyd Smith

18

:내장은 이미이었다 톰슨 쉘 이 있어요 - 문서화 를위한 유닉스 V6 , 톰슨 쉘에서 1975 년 :에 대한 레이블 표시 goto명령을 사용합니다. 로 goto시작하는 전화 를 한 번도 시도하지 않은 경우 해당 라인은 사실상 주석입니다.

Bourne 쉘 , Bourne의 / POSIX 쉘의 조상 우리가 그들을 알고는 없었 goto내가 아는 것을, 그러나 유지 :노 연산 명령 (가 이미 존재로 유닉스 V7 ).


11

Kernighan과 Pike의 "UNIX Programming Environment"(c) 1984라는 구식 참고 문헌을 찾았습니다.

Page 147 (Shell Programming)은 다음과 같이 말합니다.

":"는 셸 내장 명령으로 인수를 평가하고 "true"를 반환합니다. 대신 [스크립트 예제 참조] true 종료를 사용하여 true를 사용할 수 있습니다 . ( false 명령도 있습니다.) 그러나 ':'은 파일 시스템에서 명령을 실행하지 않기 때문에 true보다 효율적 입니다. [이탤릭체 / 강조는 내 것이다.]


2
물론 true많은 시스템에서 셸이 내장되어 있습니다.
트리플 리

8

셸의 초기 버전에는 주석 구문이 없었습니다. :(와 비슷한 실제 실행 파일이었을 것임)으로 시작하는 줄 /bin/true이 최선의 대안이었습니다.

다음 은 고대 톰슨 쉘에 대한 매뉴얼 페이지 입니다 (관계 없음). 주석 구문에 대한 언급은 없습니다.


4
:사실 기원은 goto일부 고대 껍질에서 명령에 대한 레이블 표시기였습니다 (어떤 것을 모르겠습니다). : something일치 하는 레이블 이 없으면 레이블을 주석으로 사용할 수 있습니다 goto. 연습은 goto사라진 후에도 멈췄다.
Gilles 'SO- 악마 그만해'

8

":"는 디버깅에 편리합니다.

DEBUGLOG=": debugfunction"

statement
statement
$DEBUGLOG arg1 arg2 ...
statement
statement

정상적으로 실행되면 디버그 기능이 실행되지 않으므로 noop 위로 넘어가십시오 (변수 및 와일드 카드는 확장됩니다). 더 자세한 디버깅이 필요한 경우 변수에서 noop을 제거하고 필요한 인수가 있으면 debugfunction이 호출됩니다.

또 다른 편리한 사용법은 블록 주석으로, 쉘 구문에서 누락 된 기능입니다.

: << COMMENT
all --statements --in --here
are now -a here document which are
passed to --the noop
COMMENT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.