stdin이 쉘 함수로 파이프되는지 감지

stdin이 쉘 함수로 파이프되는지 감지

나는 명령줄 환경과 쉘 스크립트에서 많은 쉘 기능을 사용합니다. 데이터가 파이프로 연결되는지 여부에 따라 두 가지 합계가 다르게 동작하기 upper를 원합니다 . lower현재 작성된 두 함수 모두 전달된 인수를 통해 입력을 받습니다.

이는 다음의 정의입니다 upper.

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

이는 다음의 정의입니다 lower.

lower () {
    my_echo "${1}" | tr "[:upper:]" "[:lower:]"
    return 0
}

( my_echo는 를 대체하기 위해 작성한 Python 스크립트입니다 echo. 이스케이프 시퀀스를 리터럴로 변환하는 동안 인수로 전달된 모든 내용을 출력해야 합니다. 문자열을 옵션으로 해석하지 않고 인쇄할 수 있습니다. Unix 콘솔이 작동하는 방식은 방해가 됩니다. 이 목표는 무시할 수 있도록 따로 보관해 두었습니다 -e. )echo

이러한 기능에는 이전 버전이 여러 개 있습니다. 표준 입력에서 실행되는 버전에 대한 정의는 다음과 같습니다.

upper () {
    tr "[:lower:]" "[:upper:]"
}

lower () {
    tr "[:upper:]" "[:lower:]"
}

함수가 파이프로 연결된 경우 위와 같이 작동해야 합니다. 그렇지 않은 경우 첫 번째 인수를 읽어야 합니다.

답변1

귀하의 코드:

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

인수가 없으면 표준 입력에서 읽습니다.

upper () {
    ( (( $# )) && printf '%s\n' "$@" || cat ) |
    tr '[:lower:]' '[:upper:]'
}

이는 $#위치 인수의 수를 테스트하고, 해당 숫자가 0이면 cat표준 입력 스트림에서 읽은 데이터를 사용하고, 그렇지 않으면 printf위치 인수를 사용합니다. 그런 다음 tr.

return 0파이프의 실제 종료 상태를 알고 싶을 수도 있기 때문에 제거했습니다 .

에서는 bash다음을 수행할 수 있습니다.

upper () {
    (( $# )) && printf '%s\n' "${@^^}" || tr '[:lower:]' '[:upper:]'
}

이것은 인수가 있는 경우 전혀 사용되지 않지만 tr대신 Bash의 ${parameter^^pattern}대체를 사용하여 모든 인수를 대문자로 변환합니다( ,,소문자 사용).

printf형식 문자열을 변경할 수도 있고 변경하지 않을 수도 있으므로 달성하려는 목표 '%s '에 따라 다릅니다 .'%s\n'

관련 정보