How to inject a wav file in to a bash script
Posted: Mon Aug 03, 2020 2:10 am
This is from the Murga Forum, first Posted: Sat 30 Dec 2017, I thought I'd retrieve the conversation, as it's an obscure process that hasn't found a use in puppy as far as I know.
I really hope the Murga Forum can be saved.
I am so grateful to all those that have added to the vast amount of knowledge that I have often accessed that helped me, I knew little to nothing before joining the Puppy forum, thank you everyone.
I really hope the Murga Forum can be saved.
I am so grateful to all those that have added to the vast amount of knowledge that I have often accessed that helped me, I knew little to nothing before joining the Puppy forum, thank you everyone.
Geoffrey: I was wondering if was possible for a script to carry binary data, after a bit of searching I found the answer I was looking for, so made this example.
This script when run will extract the data to /tmp as chime.wav, then play the wav file as a sequence derived from the clock, to chime the hours.
Will work to chime the hours if run with Pschedule on the hour.In a working directory to build this place the chime.wav, then create a script with the above code and name it hour_chimeCode: Select all
#!/bin/bash dd if="$0" of=/tmp/chime.wav bs=1 skip=131 hours=`date +"%-l"` seq "$hours" | xargs -I{} aplay -q /tmp/chime.wav exit;
Open a terminal in the working directory and paste the above code and run it, this injects the wav data in to the script.Code: Select all
cat chime.wav >> hour_chime chmod +x hour_chime
The script is now a standalone not requiring any external file to function.
The important thing is the skip=? this needs to be precise else the extracted data will be corrupted.
MochiMoppel:
Geoffrey wrote:
I was wondering if was possible for a script to carry binary data
Nothing is impossible but it has the potential for desaster. Bash tries to interpret binary rubbish:
Your exit command bumps into the header of the wav file, which makes it "exitRIFFr", i.e. your script will not exit at this point. Make it exit; and change the skip value to 131. Still I can't see the usefulness of this exercise.Code: Select all
# /opt/hour_chime 56954+0 records in 56954+0 records out 56954 bytes (57 kB) copied, 0.447853 s, 127 kB/s /opt/hour_chime: line 6: $'exitRIFFr\336WAVEfmt': command not found /opt/hour_chime: line 7: $'S\031\365\v\230\363=\b~\E\225\350y\317H\376\274\035\342\231\031&\374 \331\316\242\343\300\004\327\025\260': command not found /opt/hour_chime: line 10: syntax error near unexpected token `)' /opt/hour_chime: line 10: `)þÙâä×æ¶ïC % ð\ç«{*×?õrþºã]ڻõ)^0 wÛ9ãÕë¢õd"³)IüëßÄþá _në1íºõú¨õN¨õô¯µïYÌîóÐ#̹õæôXþ©ëñïö2ù«X+»r÷؍µTæÓ9<:4 Ííçù÷Ü*û³:Â<÷.̟ÄéϾ' # 1;2c1;2c^C
Geoffrey:
MochiMoppel wrote:
Your exit command bumps into the header of the wav file, which makes it "exitRIFFr", i.e. your script will not exit at this point. Make it exit; and change the skip value to 131. Still I can't see the usefulness of this exercise.
Ah! thanks, updated the first post, more a curiosity than a having a purpose for it, then you never know when it may find a purpose, just handy to know it can be done.
MochiMoppel:
Geoffrey wrote:
more a curiosity than a having a purpose for it
That's a valid reason
Let's try to make it a bit smarter. There is no need to extract the audio data into a tmp file. You can make the bash script "play itself". Create a script, let's call it header:
Make sure that the code has 90 characters, then combine header and chime.wav into a new script hourlychime.sh:Code: Select all
#!/bin/bash for ((c=1;c<=$(date +%l);c++));do dd if="$0" bs=1 skip=90 | aplay; done exit;
From here there is no limit to insanity: You can add a timer loop, so you won't need pschedule, you can pack more than one audio file into this script and even a player ... OK, I leave it to your curiosity.Code: Select all
cat header chime.wav > hourlychime.sh ; chmod +x hourlychime.sh Running hourlychime.sh will pipe the embedded audio data directly to aplay.
musher0:
Hi guys.
This technique is fascinating. Thanks to MochiMoppei for revisions and suggestions, and of
course to Geoffrey for initiating this thread.
Geoffrey, in the 1st line of your OP, you mention some research you did. Would you care to
share a few URLs about this technique for our benefit? TIA.
BTW, does this technique have a name?
BFN
_________________
musher0
~~~~~~~~~~
Je suis né pour aimer et non pas pour haïr. (Sophocle) /
I was born to love and not to hate. (Sophocles)
amigo:
Think about those *.run files -they are self-extracting scripts. The payload is a tarball or zipped file or whatever. Inside the script you have marker or other method to skip over the first script part, starting from the marker or offset and procesing that with whatever. You can use 'sed', 'head', 'cut', 'dd' or many other ways to skip to the payload and pipe that through whatever.
By appending such binary data, you can even have an 'exit' in your script to make sure the script will never get there.
Geoffrey:Brilliant, that was my initial want, I just got lazy LaughingMochiMoppel wrote:
Let's try to make it a bit smarter. There is no need to extract the audio data into a tmp file. You can make the bash script "play itself"
https://stackoverflow.com/questions/276 ... fficientlymusher0 wrote:
share a few URLs about this technique for our benefit?
BTW, does this technique have a name?
amigo wrote:
Think about those *.run files -they are self-extracting scripts.
That had crossed my mind during my search http://makeself.io/
seaside:
Here's another way using tail.
Code: Select all
#!/bin/bash #chime.wav #cat header chime.wav > hourlychime.sh ; chmod +x hourlychime.sh hours=`date +"%-l"` size=`stat -c %s chime.wav` for (( i=1; i <= $hours; i++ )); do tail -c $size hourlychime.sh | aplay; done exit;
Cheers,
s
musher0:
Thanks, Geoffrey.
I wish you and all Puppyists a "Happy, Healthy and Successful New Year 2018"! Smile
_________________
musher0
~~~~~~~~~~
Je suis né pour aimer et non pas pour haïr. (Sophocle) /
I was born to love and not to hate. (Sophocles)
vovchik:
Dear all,
Thanks for the examples. I learned something, as I usually from many posts on this forum. I wish you all a happy, prosperous and rewarding new year!
WIth kind regards,
vovchik
Geoffrey:
seaside wrote:
Here's another way using tail.
Code: Select all
#!/bin/bash #chime.wav #cat header chime.wav > hourlychime.sh ; chmod +x hourlychime.sh hours=`date +"%-l"` size=`stat -c %s chime.wav` for (( i=1; i <= $hours; i++ )); do tail -c $size hourlychime.sh | aplay; done exit;
Cheers,
s
That's good, here's a script to create the hourlychime.sh, just drag the wav file to it
Code: Select all
#!/bin/bash SCRIPT="hourlychime.sh" touch "$SCRIPT" echo '#!/bin/bash SCRIPT="$(readlink -e "$0")" for (( i=1; i <= `date +"%-l"`; i++ )); do tail -c '$"`stat -c %s "$1"`"' "$SCRIPT" | aplay -q; done exit;' > "$SCRIPT" cat "$1" >> "$SCRIPT" ; chmod +x "$SCRIPT"
Happy new year
EDIT: Strangely enough this doesn't work from outside the directory it's in, I need to change directory in terminal for it to run, even if it's in /usr/bin
EDIT 2: fixed tail couldn't find the path
Code: Select all
SCRIPT="$(readlink -e "$0")"
musher0:
Powerful stuff. Careful what you wish!!! Wink
Someone could hide a < remove all command > in there!
_________________
musher0
~~~~~~~~~~
Je suis né pour aimer et non pas pour haïr. (Sophocle) /
I was born to love and not to hate. (Sophocles)
jamesbond:
Here: http://makeself.io/amigo wrote:
Think about those *.run files -they are self-extracting scripts. The payload is a tarball or zipped file or whatever.
It's actually quite popular. VirtualBox generic Linux binaries for example are packaged with makeself. Nvidia proprietary drivers too.