Bash 4.3에서 실행되고 rpm 패키지를 확인하는 스크립트가 있습니다. 동일한 스크립트가 bash 4.4에서 성공적으로 실행되기를 원하지만 스크립트에서 경고가 발생합니다 “warning: command substitution: ignored null byte in input”
. 이 경고를 발생시키는 줄은 다음과 같습니다.
FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0
스크립트는 다음과 같이 디버그 모드에서 실행됩니다.
+++ find /opt/RPM/components -type d -name eum-1.1.6 -print0
bash: warning: command substitution: ignored null byte in input
++ LINSEE_RPM=/opt/RPM/components/enum-1.1.6
이 경고를 무시하고 bash4.3에서처럼 이 null 바이트를 자동으로 제거하려면 지금 이 줄을 어떻게 다시 작성해야 합니까?
답변1
\0
이 옵션 -print0
으로 생성된 바이트를 사용하지 않으므로 다음 을 수행해야 할 수 있습니다.
FIND_RPM="$(find /opt/RPM/components -type d -name enum-1.1.6 -print)"
답변2
그런데 어떤 이유로 -print0
찾기 옵션을 유지해야 하는 경우(예: 결과에 새 줄을 포함하려는 경우) bash 4.4에서 다른 방법을 사용하여 이를 수행하고 결과 연결을 피할 수 있습니다. Bash는 변수에 할당할 때 null 바이트에 대해 불평하지만 프로세스 대체에서는 문제 없이 null 바이트를 처리합니다.
여러 결과가 예상되는 경우 배열이 필요할 가능성이 높습니다.
$ IFS= readarray -t -d '' array < <(find . -type f -name 'a*.sh' -print0)
$ declare -p array
declare -a array=([0]="./appslist.sh" [1]="./advfind2.sh" [2]="./autorotate.sh" [3]="./autorot.sh" [4]="./advfind.sh" [5]="./appslist(draft).sh")
하나의 결과만 예상하는 경우:
$ IFS= read -r -d '' var < <(find . -type f -name 'autorot.sh' -print0)
$ declare -p var
declare -- var="./autorot.sh"
참고로 이 널 바이트 제거 동작은 다른 쉘에서는 작동하지 않습니다. 예를 들어 zsh
명령 은 여러 결과에서도 문제 없이 작동 zsh
합니다 .-print0
zsh$ var=$(find . -type f -name 'auto*.sh' -print0)
zsh$ declare -p var
typeset var=$'./autorotate.sh\C-@./autorot.sh\C-@'
zsh$ echo "$var" |od -w32 -t x1c
0000000 2e 2f 61 75 74 6f 72 6f 74 61 74 65 2e 73 68 00 2e 2f 61 75 74 6f 72 6f 74 2e 73 68 00 0a
. / a u t o r o t a t e . s h \0 . / a u t o r o t . s h \0 \n
답변3
귀하의 명령은 동일하게 유지되며(질문의 구문이 유효하지 않더라도 복사-붙여넣기 문제일 수 있음) bash 4.3 및 bash 4.4에서 동일하게 작동합니다.
NULL 바이트는 여전히 삭제됩니다. 유일한 차이점은 경고 메시지가 추가된다는 것입니다.배쉬 4.4 패치 2
귀하의 경우 명령은 하나의 항목만 찾기 때문에 작동합니다. 여러 항목이 발견되면 항목이 연결됩니다(널 바이트가 제거되기 때문).
명령을 다음으로 변경합니다.
FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6)
문제를 해결하지만 경로에 개행 문자가 포함되어 있으면 여전히 차단됩니다.
답변4
FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0
아마도 그래야 할 것이다
FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6 -print0)
그러나 그것이 경고 메시지의 이유는 아닙니다.
-print0
with를 사용하면 (0 없이) 에 의해 생성된 일반적인 개행 문자 대신 발견된 경로 사이의 구분 기호로 find
널 바이트( , ASCII 0)가 출력됩니다 .$'\0'
find
-print
일반적으로 -print0
경로를 보내는 데 사용됩니다.가능한공백이나 기타 공백 문자 xargs
또는 널 바이트 종료 경로를 처리하는 방법을 아는 기타 유틸리티가 포함되어 있습니다. 이는 경로의 외부 파일 이름을 올바르게 처리합니다(Nul 바이트는 Unix에서 파일 이름의 일부가 아닐 수 있지만 공백이나 개행은 포함될 수 있음).
-print0
귀하의 경우 에는 -print
.
이는 여러 경로가 발견되는 경우 유효한 경로를 제공하는 효과도 있습니다. 를 사용하면 -print0
Bash는 nul을 제거하고 경로를 연결합니다.