IT

bash에서 noop [:]의 사용 사례는 무엇입니까?

lottoking 2020. 8. 12. 07:25
반응형

bash에서 noop [:]의 사용 사례는 무엇입니까?


bash (:)에서 noop을 검색했지만 좋은 정보를 수 없었습니다. 이 연산자의 목적 목적 또는 사용 사례는 무엇입니까?

나는 다음을 시도하고 그것은 나를 위해 다음과 같이 작동합니다.

[mandy@root]$ a=11
[mandy@root]$ b=20
[mandy@root]$ c=30
[mandy@root]$ echo $a; : echo $b ; echo $c
10
30

이 운영자의 실시간 사용 사례 또는 반드시 사용하는 곳을 알려주세요.


역사적인 많이 더 많이 있습니다. 내장 콜론 :은 정확히 true. true예를 들어 무한 루프에서 반환 값이 중요 할 때 사용하는 것이 일반적입니다 .

while true; do
  echo 'Going on forever'
done

:셸 구문에 명령이 필요하지만 사용하는 것이 일반적 입니다.

while keep_waiting; do
  : # busy-wait
done

:모든 내장 날짜받는 방식을 다시 톰슨 쉘 , 그것은 현재유닉스 버전 6 . :Thompson 쉘의 goto전시에 대한 라벨 표시기입니다 . 레이블은 텍스트가 될 수 있으므로 :(있을 경우 코멘트 더 지표로 두 배로 goto comment하고 : comment효과적으로 주석 없음). Bourne 쉘은 하지 않았다 goto하지만 유지 :.

관용구가 사용 일반적인하는 것을 :입니다 , 세트 어떤 이 설정되지 않은이었고, 아무것도하지 않는 경우 경우 이미 설정되었다. 이 구조는 변수 대체의 형태로만 존재하며이 변수 대체는 어떤 식 으로든 명령의 일부 택합니다. no-op 명령은 훌륭하게 작동합니다.: ${var=VALUE}varVALUEvar

콜론 내장어떤 용도로 사용 검증? .


모든 코드를 주석 처리 할 때 문에 사용합니다. 예를 들어 테스트가 있습니다.

if [ "$foo" != "1" ]
then
    echo Success
fi

그러나 그 안에 포함 된 모든 것을 일시적으로 주석 처리하고 싶습니다.

if [ "$foo" != "1" ]
then
    #echo Success
fi

이로 인해 bash가 구문 오류가 제공됩니다.

line 4: syntax error near unexpected token `fi'
line 4: `fi'

Bash는 빈 블록 (WTF)을 수 없습니다. 따라서 no-op을 추가합니다.

if [ "$foo" != "1" ]
then
    #echo Success
    :
fi

또는 no-op을 사용하여 줄을 주석 처리 할 수 ​​있습니다.

if [ "$foo" != "1" ]
then
    : echo Success
fi

set- e그러면 을 사용 하면 실패가 발생해도 펼쳐서 종료 하지 않는|| : 좋은 방법입니다 (명시 적으로 통과하게 함).


:성공하지만 아무것도 수행하지 않는 명령을 제공하는 데 사용 합니다. 이 예에서 "verbosity"명령은로 설정하여 기본적으로 해제 :됩니다. 'v'옵션은이를니다니다.

#!/bin/sh
# example
verbosity=:                         
while getopts v OPT ; do          
   case $OPT in                  
       v)        
           verbosity=/bin/realpath 
       ;;
       *)
           exit "Cancelled"
       ;;             
   esac                          
done                              

# `$verbosity` always succeeds by default, but does nothing.                              
for i in * ; do                   
  echo $i $($verbosity $i)         
done                              

$ example
   file

$ example -v
   file /home/me/file  

alias인수 무시

어떤 경우에는 인수를 사용하지 않는 별칭을 원합니다. 다음을 사용하여 수행 할 수 있습니다 :.

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there

한 가지 용도는 여러 줄 주석으로 사용하거나 here 파일과 함께 사용하여 테스트 목적으로 코드의 일부를 주석 처리하는 것입니다.

: << 'EOF'

This part of the script is a commented out

EOF

EOF내부의 코드가 평가되지 않도록 따옴표를 사용하는 것을 잊지 마십시오 $(foo). 또한 같은 직관적 인 터미네이터 이름을 사용할 가치가있다 NOTES, SCRATCHPAD또는 TODO.


내 두 명.

POD 주석 삽입

의 상당히 펑키 한 응용 프로그램은 bash 스크립트에 POD 주석:포함하는 것이므로 man 페이지를 빠르게 생성 할 수 있습니다. 물론, 결국 Perl에서 전체 스크립트를 다시 작성합니다 ;-)

런타임 함수 바인딩

이것은 런타임에 함수를 바인딩하기위한 일종의 코드 패턴입니다. Fi, 특정 플래그가 설정된 경우에만 디버깅 기능이 있습니다.

#!/bin/bash
# noop-demo.sh 
shopt -s expand_aliases

dbg=${DBG:-''}

function _log_dbg {
    echo >&2 "[DBG] $@"
}

log_dbg_hook=':'

[ "$dbg" ] && log_dbg_hook='_log_dbg'

alias log_dbg=$log_dbg_hook


echo "Testing noop alias..."
log_dbg 'foo' 'bar'

당신은 얻을 :

$ ./noop-demo.sh 
Testing noop alias...
$ DBG=1 ./noop-demo.sh 
Testing noop alias...
[DBG] foo bar

때때로 no-op 절은 코드를 더 읽기 쉽게 만들 수 있습니다.

그것은 의견의 문제 일 수 있지만 여기에 예가 있습니다. 두 개의 유닉스 경로를 사용하여 작동하는 함수를 만들었다 고 가정 해 보겠습니다. 한 경로에서 다른 경로로 cd하는 데 필요한 '경로 변경'을 계산합니다. 경로가 모두 '/'로 시작해야하거나 둘 다 시작하지 않아야한다는 제한을 함수에 적용합니다.

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        true      # continue with function
    else
        return 1  # Skip function.
    fi

일부 개발자는 no-op을 제거하고 싶지만 조건부 부정을 의미합니다.

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" != / || "$fromC" == / ]] && [[ "$toC" == / || "$fromC" != / ]]
    then
        return 1  # Skip function.
    fi

이제-내 의견으로는-함수 수행을 건너 뛰고 싶은 조건이 if 절에서 명확하지 않습니다. no-op을 제거하고 명확하게 수행하려면 if 절을 함수에서 제거해야합니다.

    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        cdPath=$(chgPath pathA pathB)   # (we moved the conditional outside)

더 좋아 보이지만 여러 번 우리는 이것을 할 수 없습니다. 함수 내에서 확인이 수행되기를 원합니다.

그래서 얼마나 자주 이런 일이 발생합니까? 자주는 아닙니다. 아마도 일년에 한두 번. 충분히 자주 발생하므로 알고 있어야합니다. (언어에 관계없이) 내 코드의 가독성을 향상 시킨다고 생각할 때 나는 그것을 사용하는 것을 주저하지 않습니다.


이 답변 과 다소 관련 있으므로이 no-op은 다중 언어 스크립트 를 해킹하는 데 다소 편리합니다 . 예를 들어, 다음은 bash와 vimscript 모두에 대한 유효한 주석입니다.

":" #    this is a comment
":" #    in bash, ‘:’ is a no-op and ‘#’ starts a comment line
":" #    in vimscript, ‘"’ starts a comment line

물론 우리도 true똑같이 사용했을 수도 있지만 :, 관련없는 영어 단어가 아닌 구두점 기호는 그것이 구문 토큰이라는 것을 분명히합니다.


누군가가 다국어 스크립트를 작성하는 것과 같이 까다로운 일을하는 이유관해서 는 (멋진 것 외에도) : 일반적으로 file을 X참조하는 파일 과 함께 여러 다른 언어로 여러 스크립트 파일을 작성하는 상황에서 도움 이됩니다 Y.

이러한 상황에서 두 스크립트를 단일 X다중 언어 파일로 결합하면 경로를 결정하는 작업을 피할 수 있습니다 Y(단순히 "$0"). 더 중요한 것은 프로그램을 이동하거나 배포하는 것이 더 편리하다는 것입니다.

  • 일반적인 예입니다. shebangs에는 잘 알려진 오랜 문제가 있습니다. 대부분의 시스템 (Linux 및 Cygwin 포함)은 하나의 인수 인터프리터에 전달할 수 있습니다. 다음 shebang :

    #!/usr/bin/env interpreter --load-libA --load-libB
    

    다음 명령을 실행합니다.

    /usr/bin/env "interpreter --load-libA --load-libB" "/path/to/script"
    

    의도 한 것이 아닙니다.

    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"
    

    따라서 다음과 같은 래퍼 스크립트를 작성하게됩니다.

    #!/usr/bin/env sh
    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"
    

    이것은 다 색체가 무대에 들어가는 곳입니다.

  • 더 구체적인 예입니다. 저는 한때 Vim을 호출하는 bash 스크립트를 작성했습니다. Vim에 추가 설정을 제공해야했는데 이는 옵션으로 수행 할 수 있습니다 --cmd "arbitrary vimscript command here". 그러나 그 설정은 상당했기 때문에 문자열에 인라인하는 것은 끔찍했습니다 (가능하다면). 따라서 더 나은 해결책은 일부 구성 파일의 extenso작성한 다음 Vim이 -S "/path/to/file". 따라서 나는 다국어 bash / vimscript 파일로 끝났습니다.


다른 명령의 성공에 연결하려는 명령이 있다고 가정합니다.

cmd="some command..."
$cmd
[ $? -eq 0 ] && some-other-command

그러나 이제 명령을 조건부로 실행하고 실행될 명령을 표시하려고합니다 (드라 이런).

cmd="some command..."
[ ! -z "$DEBUG" ] && echo $cmd
[ -z "$NOEXEC" ] && $cmd
[ $? -eq 0 ] && {
    cmd="some-other-command"
    [ ! -z "$DEBUG" ] && echo $cmd
    [ -z "$NOEXEC" ] && $cmd
}

따라서 DEBUG 및 NOEXEC를 설정하면 두 번째 명령이 표시되지 않습니다. 이것은 첫 번째 명령이 실행되지 않기 때문입니다 (NOEXEC가 비어 있지 않기 때문에).하지만 그 사실을 평가하면 1이 반환됩니다. 즉, 하위 명령이 실행되지 않는다는 의미입니다 (하지만 테스트 실행이기 때문에 실행하려는 경우). 이 문제를 해결하려면 noop을 사용하여 스택에 남아있는 종료 값을 재설정 할 수 있습니다.

[ -z "$NOEXEC" ] && $cmd || :

참고 URL : https://stackoverflow.com/questions/12404661/what-is-the-use-case-of-noop-in-bash

반응형