명령줄에서 NUL 표현/인용

명령줄에서 NUL 표현/인용

\0명령줄에서 사용할 수 있나요 ?

배경

GNU Parallel의 특수 사례를 테스트하기 위해 명령줄에서 모든 문자가 올바르게 인용되었는지 궁금했습니다. 대부분은 다음과 같습니다.

perl -e 'print pack ("c*",1..255,10)' | parallel -k echo | md5sum
d03484ca75b3e38be411198d66bf4611  -
perl -e 'print pack ("c*",1..255,10)' | md5sum
d03484ca75b3e38be411198d66bf4611  -

하지만 \0까다로운 것 같습니다(여기서는 로 설명됨 A\0B\n).

perl -e 'print pack ("c*",65,0,66,10)' | wc -c
4 (A\0B\n)
perl -e 'print pack ("c*",65,0,66,10)' | parallel echo | wc -c
2 (A\n)
perl -e 'print pack ("c*",65,0,66,10)' | parallel --dry-run echo | wc -c
9 (echo A\0B\n)
perl -e 'print "echo ",pack ("c*",65,0,66,10)' | bash | wc -c
3 (AB\n)

두 번째 예를 정당화할 수 있습니다. \0EOS로 해석될 수 있지만 예 4에서도 마찬가지입니다. 예 3에서는 GNU Parallel이 \0EOS로 간주 하지 않고 bash.

무슨 일이 일어나고 있는지 설명해 주시겠습니까? 특히 사례 4가 저를 당황하게 합니다.

그리고 더 중요한 것은:

예 를 들어 볼 수 \0있도록 명령줄에서 인용하는 방법이 있습니까 ?echo

답변1

명령을 실행할 때 인수 목록은 execve()시스템 호출에 전달된 NUL 종료 문자열에 대한 포인터 목록입니다( 에 전달된 다른 NUL 종료 문자열 목록인 환경 변수와 유사 execve()).

결과적으로, 인수와 환경 변수는처형된명령에는 NUL 문자가 포함될 수 없습니다.

인수에 무엇이든 포함될 수 있는 내장 및 함수는 예외입니다 zsh(이것들은 내장되어 있으므로 execve()시스템 호출이 관련되지 않습니다).

stdin(또는 다른 파일 설명자)을 통해 또는 모든 유형의 파일에서 NUL 문자가 포함된 데이터를 전달할 수 있습니다. 또는 일부 명령은 특정 형태의 인코딩을 이해합니다.

예를 들어, UNIX 규격 echo구현에서는 \0(두 문자 백슬래시와 0)을 NUL 문자를 의미하는 것으로 이해합니다. 일부 다른 구현에서는 -e플래그가 전달된 경우에만 이를 수행합니다.

그래서:

echo '\0'

또는:

echo -e '\0'

echoNUL 문자 다음에 LF 문자가 출력 될 수 있습니다 .

와 함께 zsh,

echo $'\0'

NUL 문자를 echo내장에 전달합니다.

/bin/echo $'\0'

작동하지 않을 것 /bin/echo입니다.처형된이므로 해당 인수에는 NUL 문자가 포함될 수 없습니다.

포인트 4 질문에 관해서. bash는 해당 NUL 문자를 무시합니다. 일부 다른 쉘은 다르게 동작합니다.

$ printf 'e\0cho a\0b\n' | bash |& sed -n l
ab$
$ printf 'e\0cho a\0b\n' | ksh |& sed -n l
ksh: syntax error at line 1: `zero byte' unexpected$
$ printf 'e\0cho a\0b\n' | zsh |& sed -n l
zsh: command not found: e$
$ printf 'e\0cho a\0b\n' | rc |& sed -n l
line 1: warning: null character ignored$
line 1: warning: null character ignored$
ab$

관련 정보