bash는 16 진수 값 0x00을 변수에 저장할 수 없습니다

dd로 몇 가지 트릭을 시도하고 있습니다. 16 진수 값을 “header”라는 변수에 저장하여 dd로 파이프하는 것이 가능하다고 생각했습니다.

변수가없는 첫 번째 단계는 다음과 같습니다.

$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex

00000000  36 c9 da 00 b4                                    |6....|
00000005

그 후 나는 이것을 시도했다 :

$ header=$(echo -ne "\x36\xc9\xda\x00\xb4")
$ echo -n $header | hd

00000000  36 c9 da b4                                       |6...|
00000004

보시다시피 변수 \x00에서 값을 잃었습니다 $header. 누구든지이 행동에 대한 설명이 있습니까? 이것은 나를 미치게합니다.



답변

Bash는 C 스타일 문자열을 사용하기 때문에 문자열에 널 바이트를 저장할 수 없습니다.이 문자열은 종료자를 위해 널 바이트를 예약합니다. 따라서 Bash가 중간에 저장하지 않고 널 바이트를 포함하는 시퀀스를 파이프하기 위해 스크립트를 다시 작성해야합니다. 예를 들어 다음과 같이 할 수 있습니다.

printf "\x36\xc9\xda\x00\xb4" | hd

그건 그렇고, 당신은 필요하지 않습니다 echo; Bash를 printf다른 많은 간단한 작업에 사용할 수 있습니다 .

또는 체인 대신 임시 파일을 사용할 수 있습니다.

printf "\x36\xc9\xda\x00\xb4" > /tmp/mysequence
hd /tmp/mysequence

물론 이것은 파일 /tmp/mysequence이 이미 존재할 수 있다는 문제가 있습니다. 이제 임시 파일을 작성하고 경로를 문자열로 저장해야합니다.

또는 프로세스 대체를 사용하여이를 피할 수 있습니다.

hd <(printf "\x36\xc9\xda\x00\xb4")

<(command)연산자의 출력을 수신 할 파일 시스템의 명명 된 파이프를 생성 command. hd첫 번째 인수로 파이프에 대한 경로를받습니다.이 파이프는 거의 모든 파일처럼 열고 읽을 수 있습니다. /unix//a/17117/136742 에서 자세한 내용을 확인할 수 있습니다 .


답변

zsh변수에 NUL 문자를 저장할 수있는 유일한 쉘인 대신 사용할 수 있습니다 . 해당 문자는 기본값 $IFSin에 zsh있습니다.

nul=$'\0'

또는:

nul=$'\x0'

또는

nul=$'\u0000'

또는

nul=$(printf '\0')

그러나 인수 및 환경 변수가 시스템 호출에 전달되는 NUL 구분 문자열 (쉘이 아닌 시스템 API의 제한) 이므로 실행 되는 명령에 인수 또는 환경 변수와 같은 변수를 전달할 수 execve()없습니다. ). 에서가 zsh, 당신은 그러나 NUL 함수 또는 명령 내장 인수로 바이트를 전달할 수 있습니다.

echo $'\0' # works
/bin/echo $'\0' # doesn't