How to write a binary file using Bash?

后端 未结 6 1840
迷失自我
迷失自我 2021-02-05 05:46

My problem is that I need to create a file with this exact bytes: 48, 00, 49, 00.

I cannot use C, perl, other scripting language (the target is an embedded

相关标签:
6条回答
  • 2021-02-05 06:29

    I don't know what's in busybox, but this might work because printf is smaller than awk.

    $ printf "%c%c%c%c" 48 0 49 0 | hexdump
    

    This is the output:

    $ printf "%c" 1 | hexdump
    0000000 0031                    
    
    0 讨论(0)
  • 2021-02-05 06:36

    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.

    Write the binary data in hex:

    # busybox printf '\x74\x65\x73\x74' > /sdcard/test.txt
    

    Display the result in hex:

    # busybox hexdump -C /sdcard/test.txt
    00000000  74 65 73 74                                       |test|
    00000004
    

    Display the result in ascii:

    # cat /sdcard/test.txt
    test
    
    0 讨论(0)
  • 2021-02-05 06:41

    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.

    $ printf '\060\000\061\000' | 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:

    $ printf '\110\000\111\000' | od -An -tx1
     48 00 49 00
    
    0 讨论(0)
  • 2021-02-05 06:42

    A couple of more general functions to output integers:

    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
    }
    

    Use to make an audio WAV file header for iio data stream:

    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 data capture to WAV file:

    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
    
    0 讨论(0)
  • 2021-02-05 06:43

    you could try echo, that also allows arbitrary ascii chars (those numbers are octal numbers).

    echo -n -e \\0060\\0000\\0061\\0000  | hexdump
    
    0 讨论(0)
  • 2021-02-05 06:48

    you can use the following command:

    echo -n -e \\x48\\x00\\x49\\x00 > myfile
    
    0 讨论(0)
提交回复
热议问题