매개변수나 파이프로부터 입력을 받을 수 있는 방식으로 다음 bash 함수를 작성하고 싶습니다.
b64decode() {
echo "$1" | base64 --decode; echo
}
필수 사용:
$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQo="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQo="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQo=" | b64decode
답변1
바라보다Stefan Chazeras의 답변더 나은 솔루션을 얻으려면.
/dev/stdin
다음을 사용하여 표준 입력에서 읽을 수 있습니다 .
b64decode()
{
if (( $# == 0 )) ; then
base64 --decode < /dev/stdin
echo
else
base64 --decode <<< "$1"
echo
fi
}
$# == 0
명령줄 인수 수가 0인지 확인하세요.base64 --decode <<< "$1"
사용 및 파이프herestring
대신 사용하는 것도 가능합니다.echo
base64
답변2
여기에서는 다음과 같아야 합니다.
b64decode() {
if [ "$#" -gt 0 ]; then
# concatenated arguments fed via a pipe.
printf %s "$@" | base64 --decode
else
base64 --decode # read from stdin
fi
ret=$?
echo # add one newline character
return "$ret" # return with base64's exit status to report decoding
# errors if any.
}
아무튼 하세요아니요사용 base64 --decode < /dev/stdin
. 기껏해야 (대부분의 시스템에서) 아무것도 하지 않고 단지 (fd 0을 fd 0에 복사, 작업 없음) < /dev/stdin
것과 동일한 작업을 수행합니다 .dup2(0,0)
그러나 Linux나 Cygwin에서는 < /dev/stdin
이것이 제대로 작동하지 않습니다. 이러한 시스템에서 열기는 /dev/stdin
stdin을 복사하는 것과 동일하지 않습니다. 처음부터 다시 열고 현재 stdin에 열려 있는 파일과 동일한 파일을 독립적으로 엽니다.
따라서 이전에 stdin이 일부 일반 파일의 중간을 가리키고 있었다면 나중에 < /dev/stdin
stdin이 현재 가리키는 결과를 얻게 됩니다.처음에파일의. stdin이 파이프의 쓰기 끝(일반적인 상황에서는 있어서는 안 됨)인 경우 결국에는 읽기 끝이 됩니다. 소켓인 경우 소켓이 불가능하므로 실패합니다.열려 있는. 읽기 위해 파일을 열 수 있는 권한이 없는 경우에도 마찬가지입니다(예: 권한이 변경되었거나 파일이 원래 다른 자격 증명을 사용하여 stdin에서 열렸기 때문에).
반환 시 base64 --decode < /dev/stdin
파일에서 stdin의 현재 위치(검색 가능한 파일 입력의 경우)는 끝(또는 base64
읽기가 중지되는 위치)에 남아 있지 않고 변경되지 않은 상태로 유지됩니다. 왜냐하면 base64
의 stdin이 다른 위치에 있기 때문입니다.파일 설명 열기.
답변3
샌딥의 답변base64
이는 유틸리티가 여러 줄을 지원하지 않기 때문에 작동합니다 . 보다 일반적인 경우에 대한 보다 일반적인 수정 사항
- 여러 명령줄 인수를 허용하는 대상 유틸리티
- 여러 줄을 포함하는 파이프 또는 리디렉션
그런가요?
my_function() {
if (( ${#} == 0 )) ; then
while read -r line ; do
target_utility "${line}"
done
else
target_utility "${@}"
fi
}
답변4
둘 다샌딥의그리고톰 로치의대답은 계몽적이고 감사하지만 target_utility "${@}"
상황에 따라 더 복잡한 코드를 나타낼 수 있습니다. if
중요한 코드를 내부 및 외부로 복제하면 else
불필요한 문제가 발생할 수 있습니다. OP의 질문이 재귀를 사용하여 완벽하게 해결되는 문제를 제시하지 못할 수도 있지만 다른 독자의 질문은 이를 사용하거나 래퍼 기능 사용을 고려하면 도움이 될 수 있습니다.
my_function() {
if (( ${#} == 0 )) ; then
while read -r __my_function ; do
my_function "${__my_function}"
done
else
target_utility "${@}"
fi
}
이 답변은 "인수 또는 파이프의 입력을 허용하는 Bash 함수"에 대해 가능한 다양한 솔루션 중 하나입니다. OP가 [주석에서] 이것이 base64
실제 문제 도메인이 아니라고 지적했기 때문입니다. 따라서 파일에서 직접 입력을 읽을 수 있는지 확인하려고 시도하지 않습니다.
다양한 의견에 따르면 이 템플릿 및 이와 유사한 다른 템플릿은 선행 공백이 있는 줄을 올바르게 처리하지 못할 수 있다는 우려가 IFS =
있습니다 read
. 실제로 쉘이 민감한 문자가 있으면 이 함수를 호출하기 전에 특별한 처리가 필요할 수 있습니다. 있는 그대로, 코드는 선행 공백이 발생하지 않는 것으로 알려져 있고 데이터 민감도가 이미터에 의해 사전 처리되는 경우 잘 작동합니다.
이것은 단지 교과서적인 예가 아닙니다. 실제 제작 스크립트에서 사용됩니다. target_utility
실제 코드 조각의 간단한 이름입니다. 이 답변은 범용 템플릿을 가정하지 않으며 추가적인 개발자 지혜가 필요하지 않습니다.
(사용자가 일반적으로 답변을 그대로 사용하기보다는 때때로 답변을 조정할 것이라고 가정하는 것이 합리적으로 보입니다.)