Kabuk komut dosyalarında düşük düzeyde ikili verilerle uğraşmak genellikle kötü bir fikirdir.
bash
değişkenler bayt 0'ı içeremez. zsh
Bu baytı değişkenlerinde saklayabilen tek kabuktur.
Her durumda, komut bağımsız değişkenleri ve ortam değişkenleri, execve
sistem çağrısına iletilen NUL sınırlandırılmış dizeler oldukları için bu baytları içeremez .
Ayrıca şunu da unutmayın:
var=`cmd`
ya da modern biçimi:
var=$(cmd)
çıkışındaki tüm satırsonu karakterlerini çıkarır cmd
. Dolayısıyla, bu ikili çıktı 0xa bayt ile biterse, depolandığında karıştırılır $var
.
Burada, örneğin ile kodlanmış verileri depolamanız gerekir xxd -p
.
hdr_988=$(head -c 988 < "$inputFile" | xxd -p)
printf '%s\n' "$hdr_988" | xxd -p -r > "$output_hdr"
Yardımcı fonksiyonları şöyle tanımlayabilirsiniz:
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
çıktı, 2 baytta 1 baytı kodladığı için alandan tasarruflu değildir, ancak onunla manipülasyonlar yapmayı kolaylaştırır (birleştirme, parçaları çıkarma). base64
4'te 3 baytı kodlayan, ancak çalışması kolay olmayan bir bayttır.
ksh93
Kabuk biçimi (kullanımları kodlayan bir yerleşiği olan base64
, onun ile kullanılır) read
ve printf
/ print
kamu:
typeset -b var # marked as "binary"/"base64-encoded"
IFS= read -rn 988 var < input
printf %B var > output
Kabuk veya env değişkenleri veya komut bağımsız değişkenleri üzerinden geçiş yoksa, kullandığınız yardımcı programlar bayt değerini işleyebildiği sürece Tamam olmalısınız. Ancak, metin yardımcı programları için, GNU olmayan uygulamaların çoğunun NUL baytlarını işleyemeyeceğini ve çok baytlık karakterlerle ilgili sorunları önlemek için yerel ayarı C olarak düzeltmek isteyeceğinizi unutmayın. Son satır, yeni satır karakteri olmamakla birlikte sorunların yanı sıra çok uzun satırlara da neden olabilir (iki 0xa bayt arasındaki bayt dizileri daha uzun LINE_MAX
).
head -c
burada bayt ile çalışmak anlamına geldiğinden ve verileri metin olarak ele almak için bir neden olmadığından burada uygun olmalıdır. Yani
head -c 988 < input > output
iyi olmalı. Uygulamada en azından GNU, FreeBSD ve ksh93 yerleşik uygulamaları sorun oluşturmaz. POSIX -c
seçeneği belirtmez , ancak head
herhangi bir uzunluktaki satırları desteklemesi gerektiğini söylüyor (sınırlı değildir LINE_MAX
)
İle zsh
:
IFS= read -rk988 -u0 var < input &&
print -rn -- $var > output
Veya:
var=$(head -c 988 < input && echo .) && var=${var%.}
print -rn -- $var > output
Hatta içinde zsh
ise, $var
NUL bayt içeren, size argüman olarak geçebilir zsh
builtins (gibi print
yukarıda) veya fonksiyonlar, ancak yürütülebilir argümanlarla gibi NUL kabuğun bağımsız bir çekirdek sınırlaması olduğunu, dizeleri ayrılmış, yürütülebilir argüman olarak.
dd
(onun ayarı tek tek bayt kopyalamak içincount
To1
). Yine de onları sakladığımdan emin değilim.