서브쉘은 어떻게 파일 대신 변수로 데이터를 반환하고 동시에 다른 로그를 출력할 수 있습니까?

서브쉘은 어떻게 파일 대신 변수로 데이터를 반환하고 동시에 다른 로그를 출력할 수 있습니까?

다음과 같은 JavaScript가 있다고 가정해 보겠습니다.

    const something = doSomething();
    
    function doSomething() {
        console.log("About to do something");
        
        const a = doSomethingElse();
        if (a == "dog") {
            console.log("Worked");
            console.log("Now let's do xyz");
            return "cat";
        } else {
            console.log("failed for some reason");
            return "horse";
        }
    }
    
    function doSomethingElse() {
        console.log("About to do more");
        console.log("Done doing more stuff");
        
        return "dog";
    }

Bash에서 이를 어떻게 달성할 수 있나요? 나중에 사용하기 위해 로그를 파일에 저장하는 대신 실시간으로 보고 싶습니까? 나는 다음과 같은 것을 생각하고 있었지만 모든 것이 뒤섞이고 bash의 return 키워드는 다른 용도로 사용되며 문자열을 허용하지 않습니다.

    something=$(doSomething);
    
    function doSomething() {
        console_log "About to do something";
        
        a=$(doSomethingElse);
        if [[$a = "dog"]]; then
            console_log "Worked";
            console_log "Now let's do xyz";
            echo "cat"; # Wish I could do return "cat" ...
        else
            console_log "failed for some reason";
            echo "horse"; # Wish I could do return "horse" ...
        fi;
    }
    
    function doSomethingElse() {
        console_log "About to do more";
        console_log "Done doing more stuff";
        
        echo 'dog'; #Wish I could do return "dog" ...
    }
    
    function console_log() {
        #Is echo the right thing, or tee, or something else ?
        echo $1;
    }

이를 달성하기 위해 여러 출력 스트림이 있지 않습니까? 또는 변수를 할당하기 위해 $()에 대한 대안이 있습니까? 티셔츠, &*, &?를 가지고 놀아보았습니다. 그리고 3>1 항목은 모두 이해할 수 없습니다... :(

CentOS 7.9에 bash 4.2.46이 있습니다.

당신의 도움을 주셔서 감사합니다:)

답변1

괜찮을 것입니다.

#! /bin/bash -

doSomething() {
    print_err "About to do something"

    a="$(doSomethingElse)"
    if [[ "$a" = "dog" ]]; then
        print_err "Worked"
        print_err "Now let's do xyz"
        printf '%s' "cat"
    else
        print_err "failed for some reason"
        printf '%s' "horse"
    fi
}

doSomethingElse() {
    print_err "About to do more";
    print_err "Done doing more stuff";
    printf '%s' 'dog'
}

print_err() {
    # Print to stderr as we do this in functions
    # that print result to stdout
    printf '%s\n' "$1" >&2
}

something="$(doSomething)"
# Making it readonly would be somewhat similar to const
readonly something

printf '%s\n' "$something"

필요:

일반적으로 말하면:

그렇지 않은 경우 [[로 교체하면 규격 [이 적용됩니다 sh."sh 호환"이란 무엇을 의미합니까?

또한 변수의 범위를 살펴보십시오.ksh bash 및 zsh를 대시하기 위해 기본 명령을 이식할 수 있는 방법이 있습니까?

당신처럼당신은 할 수 있습니다, 완성된:

set_something() {
    something='cat'
}

set_something
printf 'something="%s"\n' "$something"

흐름

JavaScript는 스트림을 처리할 수 없지만 쉘은 처리할 수 있습니다. 단순화하려면:

  • readfrom stdin, 파일 설명자 0(표준)
  • writestdout, 파일 설명자 ( 1표준 출력)
  • writestderr, 파일 설명자 ( 2표준 오류)

또한 새 파일 열기, 파일 읽기/쓰기 등도 가능합니다.

관심이 있을 수도 있다/dev/stdin, /dev/stdout 및 /dev/stderr의 이식성은 얼마나 됩니까?


반환 값.

Bash 함수는 문자열을 "반환"하지 않습니다. 사람이 이렇게 할 때:

foo="$(some command)"

some command표준 출력을 에 할당합니다 foo. 리디렉션을 변경하지 않는 경우비데이터코드로 인쇄하면 다음을 통해 볼 수 있습니다.

# In doSomething():
    printf 'a="%s"\n' "$a" >&2

# At end:
printf '"%s"\n' "$something"

당신은 얻을 것이다:

a="About to do more
Done doing more stuff
dog"
something="About to do something
failed for some reason
horse"

보시다시피 전체 출력이 할당됩니다.

뒤쪽에"고정시키다"하나할 수 있다stderr를 stdout으로 리디렉션하여 두 가지를 모두 캡처합니다 stdout.stderr

foo="$(some command 2>&1)"

종료 코드

그러나 셸 함수에는 다른 프로그램과 마찬가지로 종료 코드가 있습니다. 명시적인 반환 값이 없으면 함수 내에서 실행된 마지막 명령의 종료 상태입니다. 0문제 없습니다. 다른 모든 것은 테스트에서 버그로 간주됩니다.

간단한 예:

#! /bin/bash -

foo() {
    printf 'I am foo\n'
    return 1
}
greetings() {
    if [ "$1" = "hi" ]; then
        printf 'Hello\n'
    else
        printf 'I do not know what to do with %s\n' "$1"
        return 12
    fi
}
if foo; then
    printf 'OK\n'
else
    printf 'FAIL\n'
fi

printf '\n## Try greetings "yo":\n'
greetings yo
ecode=$?
printf 'greetings() returned %d\n' "$ecode"

printf '\n## Try greetings "hi":\n'
greetings hi
ecode=$?
printf 'greetings() returned %d\n' "$ecode"

결과:

I am foo
FAIL

## Try greetings "yo":
I do not know what to do with yo
greetings() returned 12

## Try greetings "hi":
Hello
greetings() returned 0

도움shellcheck

완벽하지는 않지만 스크립트를 확인하는 데 많은 도움이 됩니다.

명령줄 도구로 사용할 수 있습니다.온라인으로 코드 붙여넣기, 또는 편집기에 통합하세요.

예를 들어 ALE와 함께 Vim을 사용하는 경우 shellcheckVim이 설치되어 있으면 시작됩니다. 그러나 배포판과 함께 번들로 제공되는 패키지는 다소 오래되었을 수 있습니다. Ubuntu 18.04를 예로 들면 v0.4.6을 사용하세요.

https://github.com/koalaman/shellcheck

일반 쉘 스크립트

다른 사람들과 함께 플레이하세요 bash. 학습에 유용합니다. 항상 당신이하고 싶은 일에 대해 생각하십시오. 예를 들어 텍스트 처리에는 다른 도구를 사용하는 것이 거의 항상 더 좋습니다. 그런 다음 쉘 스크립트를 사용하여 서로 붙일 수 있습니다. 파이프 등을 사용하십시오 - unices 기능의 일부입니다. 여기서는 예를 들어 , , , , , , , , , , , , , , sort, , , , 등입니다.​​​​​​​​​​​​joincuttrpasteuniqfindgrepcatdatetailheadxargswcfoldcolumnpaste

대화형 쉘 스크립트는 이를 사용할 수 있을 뿐만 아니라 다양한 기능으로 쉘을 확장할 수도 있습니다.

perl보다 고급 데이터 유형 및 복잡성의 경우 , python, 및 기타 다양한 유형을 사용할 수 있으며 c, c일반적으로 이는 낮은 수준에서 시스템을 이해하는 데 매우 좋은 방법입니다.

awk등은 sed또한 텍스트 작업에 매우 강력하고 유용하며 awk배우기도 더 쉽습니다.

관련 정보