Ответ 1
вы можете использовать следующую команду:
echo -n -e \\x48\\x00\\x49\\x00 > myfile
Моя проблема в том, что мне нужно создать файл с такими точными байтами: 48, 00, 49, 00
.
Я не могу использовать C, Perl, другой язык сценариев (цель - встроенное устройство). Я пробовал это с помощью awk, и на рабочем столе это работает:
# awk 'BEGIN{ printf "%c%c%c%c", 48, 00, 49, 00 }' | hexdump
0000000 0030 0031
0000004
Однако целевая платформа работает с busybox v1.13.2, и этот код там не работает. Версия awk там не выводит ascii "0" (все остальные значения в порядке).
Каковы ваши рекомендации?
вы можете использовать следующую команду:
echo -n -e \\x48\\x00\\x49\\x00 > myfile
В стандарте POSIX AWK говорится, что передача от 0 до AWK printf в формате% c может привести к неуказанному поведению. Однако... POSIX echo также очень ограничен, и хотя восьмеричные и шестнадцатеричные спецификаторы (и -n) будут работать с GNU-эхом и встроенным BASH... Они могут работать не везде. Чтобы максимизировать вероятность того, что вы получите согласованное поведение во всех системах POSIX, лучше использовать командную строку командной строки shell, чем любой из них.
$ printf '\060\000\061\000' | od -An -tx1
30 00 31 00
Это выглядит странно для меня, хотя... Возможно, вам захочется вывести 0x48, 0x00, 0x49, 0x00 - который выглядит как довольно пилотный номер в восьмеричном формате:
$ printf '\110\000\111\000' | od -An -tx1
48 00 49 00
вы можете попробовать эхо, что также позволяет произвольные символы ascii (эти числа являются восьмеричными числами).
echo -n -e \\0060\\0000\\0061\\0000 | hexdump
Мне нужно было написать двоичные файлы из hex с помощью busybox в старой оболочке Android. Этот printf
с перенаправлением работал в моем случае использования.
Напишите двоичные данные в шестнадцатеричном формате:
# busybox printf '\x74\x65\x73\x74' > /sdcard/test.txt
Отобразить результат в шестнадцатеричном формате:
# busybox hexdump -C /sdcard/test.txt
00000000 74 65 73 74 |test|
00000004
Отобразить результат в ascii:
# cat /sdcard/test.txt
test
Пара более общих функций для вывода целых чисел:
le16 () { # little endian 16 bit binary output 1st param: integer to 2nd param: file
v='awk -v n=$1 'BEGIN{printf "%04X", n;}''
echo -n -e "\\x${v:2:2}\\x${v:0:2}" >> $2
}
le32 () { # 32 bit version
v='awk -v n=$1 'BEGIN{printf "%08X", n;}''
echo -n -e "\\x${v:6:2}\\x${v:4:2}\\x${v:2:2}\\x${v:0:2}" >> $2
}
Используйте для создания заголовка аудио файла WAV для потока данных iio:
channels=2
bits_per_sample=16
let "block_align = channels * bits_per_sample / 8"
wave_header () { # pass file name and data size as parameters; rest are constants set elsewhere
data_size=$2
let "RIFFsize = data_size + 44 - 8"
let "bytes_per_sec = sampleHz * block_align"
echo -e -n "RIFF" > $1
le32 $RIFFsize $1
echo -e -n "WAVEfmt " >> $1
le32 16 $1 # format size
le16 1 $1 #format tag: 1 = PCM
le16 $channels $1
le32 $sampleHz $1
le32 $bytes_per_sec $1
le16 $block_align $1
le16 $bits_per_sample $1 # bits per sample
echo -e -n "data" >> $1
le32 $data_size $1
}
Сбор данных Linux iio ADC в файл WAV:
sampleHz=8000
milliseconds=15 # capture length
cd /sys/bus/iio/devices/iio:device0
cat /sys/bus/iio/devices/trigger0/name > trigger/current_trigger
echo 0 > buffer/enable
echo 0 > scan_elements/in_voltage0_en #
echo 1 > scan_elements/in_voltage1_en #
echo 1 > scan_elements/in_voltage2_en #
echo 0 > scan_elements/in_voltage3_en #
echo $sampleHz > sampling_frequency
sampleHz='cat sampling_frequency' # read back actual sample rate
let "buffer_length = block_align * sampleHz * milliseconds / 1000"
echo $buffer_length > buffer/length
cd $HOME
echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable
wave_header data.wav $buffer_length
head -c $buffer_length /dev/iio:device0 >> data.wav # LE16 data
echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable
Я не знаю, что в busybox, но это может работать, потому что printf меньше, чем awk.
$ printf "%c%c%c%c" 48 0 49 0 | hexdump
Это вывод:
$ printf "%c" 1 | hexdump
0000000 0031