쉘 스크립트에서 낮은 수준의 바이너리 데이터를 다루는 것은 일반적으로 나쁜 생각입니다.
bash
변수는 바이트 0을 포함 할 수 없습니다 zsh
. 변수에 해당 바이트를 저장할 수있는 유일한 쉘입니다.
어쨌든 명령 인수 및 환경 변수는 execve
시스템 호출에 전달되는 NUL 구분 문자열이므로 해당 바이트를 포함 할 수 없습니다 .
또한 다음을 참고하십시오.
var=`cmd`
또는 현대적인 형태 :
var=$(cmd)
의 출력에서 모든 후행 줄 바꿈 문자를 제거합니다 cmd
. 따라서 이진 출력이 0xa 바이트로 끝나면에 저장 될 때 엉망이됩니다 $var
.
여기에서로 인코딩 된 데이터를 저장해야합니다 xxd -p
.
hdr_988=$(head -c 988 < "$inputFile" | xxd -p)
printf '%s\n' "$hdr_988" | xxd -p -r > "$output_hdr"
다음과 같은 도우미 기능을 정의 할 수 있습니다.
encode() {
eval "$1"='$(
shift
"$@" | xxd -p -c 0x7fffffff
exit "${PIPESTATUS[0]}")'
}
decode() {
printf %s "$1" | xxd -p -r
}
encode var cat /bin/ls &&
decode "$var" | cmp - /bin/ls && echo OK
xxd -p
출력은 1 바이트를 2 바이트로 인코딩하므로 공간 효율적이지 않지만 조작을보다 쉽게 수행 할 수 있습니다 (연결, 추출). base64
4에서 3 바이트를 인코딩하지만 작업하기 쉽지 않습니다.
ksh93
쉘은 형식 (용도를 코딩하는 내장이 base64
당신이 그와 함께 사용할 수있는) read
및 printf
/ print
유틸리티 :
typeset -b var # marked as "binary"/"base64-encoded"
IFS= read -rn 988 var < input
printf %B var > output
이제 쉘 또는 env 변수 또는 명령 인수를 통한 전달이 없으면 사용하는 유틸리티가 모든 바이트 값을 처리 할 수있는 한 괜찮습니다. 그러나 텍스트 유틸리티의 경우 대부분의 비 GNU 구현은 NUL 바이트를 처리 할 수 없으며 멀티 바이트 문자의 문제점을 피하기 위해 로케일을 C로 수정해야합니다. 줄 바꿈 문자가 아닌 마지막 문자는 또한 매우 긴 행 (두 개의 0xa 바이트 사이에서 더 긴 바이트 순서)뿐만 아니라 문제를 일으킬 수 있습니다 LINE_MAX
.
head -c
사용 가능한 곳은 바이트로 작업하기위한 것이므로 여기에서 OK이어야하며 데이터를 텍스트로 취급 할 이유가 없습니다. 그래서
head -c 988 < input > output
괜찮을거야. 실제로 적어도 GNU, FreeBSD 및 ksh93 내장 구현은 괜찮습니다. POSIX는 지정하지 않는 -c
옵션을하지만 말한다 head
길이의 라인을 지원해야한다 (이에 국한되지 LINE_MAX
)
로 zsh
:
IFS= read -rk988 -u0 var < input &&
print -rn -- $var > output
또는:
var=$(head -c 988 < input && echo .) && var=${var%.}
print -rn -- $var > output
에서조차도 NUL 바이트를 포함하는 zsh
경우 $var
, 실행 파일에 전달 된 인수가 NUL로 구분 된 문자열이므로 쉘과는 독립적으로 커널 제한이므로, 위와 같이 zsh
내장 print
또는 함수에 인수로 전달할 수 있지만 실행 파일에 대한 인수로는 전달할 수 없습니다.
dd
(그 설정 개별 바이트 복사count
에를1
). 그래도 저장에 대해 잘 모르겠습니다.