Showing posts with label bash. Show all posts
Showing posts with label bash. Show all posts

Thursday, August 1, 2013

bash - putting complicated strings/text into a variable

It is a usual practice to generate commands within a script and later execute them with eval. Or one simply want to put into a variable some weird string containing quotes and other special characters. To avoid having to quote or escape everything, just write what you want to see into the variable, here's a simple way to do it... looking at it seems so obvious but truth is I never thought about that approach before:
read -r myvar << "EOF"
STRING with quotes (') and other special characters like $ and ! and #
EOF
I came to it while trying to use sed to insert another sed command into a script. Here is how it ended up like:
read -r sed_cmd <<"EOL"
sed -i -e 's#<systemPropertyVariables#<systemPropertyVariables combine.children="append"#' testsuite/integration/*/pom.xml
EOL
sed -i -e "s%mvn%$sed_cmd\nmvn%" ts.sh

Saturday, February 4, 2012

batch convert to MP3

I've got a car MP3 player and immediately found out all my music is in various formats and it's a pain to copy something over to the player with the correct format.
Searching the net didn't show something reasonable for mass/batch/bulk converting files to mp3, at least not something that would really make the job easier. So I thought it's time for some bash again.
Here I have a script that given a list of sources which can be directories and files and a destination will go over known music files in sources and copy them to the destination with their relative paths preserved *AND* converted to MP3.
Conversion is performed by playing the file through mplayer which feeds pcm audio data to the lame mp3 encoder stdin. So a wide range of input formats are supported even video files where the first audio stream is processed.

Usage:
./cp2mp3.sh <src1> ... <srcN> <dst>


For example if you have:
$ find
./file1.flac
./dir1/file2.ogg
./dir2/dir3/file3.wav
./dir4/dir5/file4.avi
and run:
./cp2mp3.sh file1.flac dir1 dir2 dir4/dir5 <somedir>
you will end up with:
$ cd <somedir>
$ find
./file1.mp3
./dir1/file2.mp3
./dir2/dir3/file3.mp3
./dir5/file4.mp3


Script may need some small modifications depending lame or mplayer locations, lame/mplayer settings, additional file extensions might be necessary, stuff like that, but generally I think its ready to use.


Download it from here and let me know how it works for you. And before I forget again, file is licensed under GPLv3.

Wednesday, August 24, 2011

devil is in the details.. #!/bin/bash

What's wrong with this:
su user -c "bash -xe" << 'EOF'
   my script
EOF
Sometimes writing constructs you have not used million times can cost precious time, in case you are *not* absolutely sure about all implications.

There is really nothing wrong with the above code if "my script" is very short and you understand deeply what it does. But if not, you may end up with your script terminating in the middle and ext code being 0 which is something I didn't expect from a script run with `-xe` options.

In my case I had a long script that just ended in the middle on an apache-ant invocation and script result was successful in our CI system. The problem is actually that apache-ant for some reason sucked everything on its stdin which in this case happened to be the rest of my script. Bash it seems, does not read the whole input so commands and programs called from within the script can eat parts of your script.

I've no idea why the particular apache-ant build never asks questions and completes happily with < /dev/null and still it eats the stdin. Maybe that's why it took me so much time to see the cause. I hope this is the reason it took me so much time to see the cause!

Conclusion is: use what you're absolutely confident in, alternatively plan some time in ahead for debugging:
cat > script.sh << 'EOF'
   my script
EOF
su user -- -xe script.sh
P.S. "bash -c"  is also solid for one liners