如何使用 Bash 编写二进制文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5582778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a binary file using Bash?
提问by elcuco
My problem is that I need to create a file with this exact bytes: 48, 00, 49, 00
.
我的问题是我需要用这个确切的字节创建一个文件:48, 00, 49, 00
.
I cannot use C, perl, other scripting language (the target is an embedded device). I tried this using awk, and in desktop it does work:
我不能使用 C、perl、其他脚本语言(目标是嵌入式设备)。我用 awk 试过这个,在桌面上它确实有效:
# awk 'BEGIN{ printf "%c%c%c%c", 48, 00, 49, 00 }' | hexdump
0000000 0030 0031
0000004
However the target platform is running busybox v1.13.2 and this code does not work there. The awk version there does not output ascii "0" (all other values are ok).
但是目标平台正在运行 busybox v1.13.2 并且此代码在那里不起作用。那里的 awk 版本不输出 ascii "0"(所有其他值都可以)。
What are your recommendations?
你有什么建议?
回答by yohann.martineau
you can use the following command:
您可以使用以下命令:
echo -n -e \x48\x00\x49\x00 > myfile
回答by Michael Back
POSIX AWK standard says that passing a 0 to AWK's printf with %c format can result in unspecified behaviour. However... POSIX echo also is very limited, and though octal and hexadecimal specifiers (and -n) will work on GNU echo and BASH built-in... They may not work everywhere. To maximize the chance that you get consistent behaviour on all POSIX systems, it is better to use the shell command line's printf than either of these.
POSIX AWK 标准表示,将 0 传递给 %c 格式的 AWK 的 printf 会导致未指定的行为。然而...... POSIX echo 也非常有限,虽然八进制和十六进制说明符(和 -n)可以在 GNU echo 和 BASH 内置......它们可能无法在任何地方工作。为了最大限度地提高在所有 POSIX 系统上获得一致行为的机会,最好使用 shell 命令行的 printf 而不是其中任何一个。
$ printf '0$ printf '0echo -n -e \0060\0000\0061\0000 | hexdump
01# busybox printf '\x74\x65\x73\x74' > /sdcard/test.txt
0' | od -An -tx1
48 00 49 00
01# busybox hexdump -C /sdcard/test.txt
00000000 74 65 73 74 |test|
00000004
0' | od -An -tx1
30 00 31 00
This looks odd to me though... You may be wanting to output 0x48, 0x00, 0x49, 0x00 -- which looks like a pretty pilot number in octal:
虽然这对我来说看起来很奇怪......你可能想要输出 0x48, 0x00, 0x49, 0x00 -- 这看起来像一个漂亮的八进制飞行员数字:
# cat /sdcard/test.txt
test
回答by flolo
you could try echo, that also allows arbitrary ascii chars (those numbers are octal numbers).
你可以试试 echo,它也允许任意的 ascii 字符(这些数字是八进制数字)。
le16 () { # little endian 16 bit binary output 1st param: integer to 2nd param: file
v=`awk -v n= 'BEGIN{printf "%04X", n;}'`
echo -n -e "\x${v:2:2}\x${v:0:2}" >>
}
le32 () { # 32 bit version
v=`awk -v n= 'BEGIN{printf "%08X", n;}'`
echo -n -e "\x${v:6:2}\x${v:4:2}\x${v:2:2}\x${v:0:2}" >>
}
回答by BuvinJ
I needed to write binary files from hex using busybox within an old Android shell. This printf
with a redirect worked in my use case.
我需要在旧的 Android shell 中使用 busybox 从十六进制编写二进制文件。这printf
在我的用例中使用了重定向。
Write the binary data in hex:
以十六进制写入二进制数据:
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=
let "RIFFsize = data_size + 44 - 8"
let "bytes_per_sec = sampleHz * block_align"
echo -e -n "RIFF" >
le32 $RIFFsize
echo -e -n "WAVEfmt " >>
le32 16 # format size
le16 1 #format tag: 1 = PCM
le16 $channels
le32 $sampleHz
le32 $bytes_per_sec
le16 $block_align
le16 $bits_per_sample # bits per sample
echo -e -n "data" >>
le32 $data_size
}
Display the result in hex:
以十六进制显示结果:
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
Display the result in ascii:
以 ascii 显示结果:
$ printf "%c%c%c%c" 48 0 49 0 | hexdump
回答by Hal Sampson
A couple of more general functions to output integers:
几个更通用的函数来输出整数:
$ printf "%c" 1 | hexdump
0000000 0031
Use to make an audio WAV file header for iio data stream:
用于为 iio 数据流制作音频 WAV 文件头:
##代码##Linux iio ADC data capture to WAV file:
Linux iio ADC数据采集到WAV文件:
##代码##回答by drysdam
I don't know what's in busybox, but this might work because printf is smaller than awk.
我不知道busybox 中有什么,但这可能会起作用,因为printf 比awk 小。
##代码##This is the output:
这是输出:
##代码##