Prev: Examine standard output and exit immediately if the exit codeis non-zero?
Next: What is the most portable syntax of these two choices?
From: Allodoxaphobia on 26 Jul 2010 16:59 I'm sure this will be casual to the most obvious observer. :-) But, I can't seem to wrap my head around it... I'm writing a script to convert audio files from one format (.aac) to another (.mp3), and the ID3 tags need to be set in the MP3 files after the conversion. I've got the extract-the-tags-from-the-aac-file (`exiftool`) piece working Just Fine. It's the piece that stuffs-the-tags-into-the-mp3-file that's got me all tied in knots. I've distilled my problem to a 'simple' case: This works: : |$ cat tst9 |#!/bin/bash | | echo 'Resetting: mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3' | | mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3 | | echo 'Executing: mp3info -t "T1 T2" -a "A1 A2" -g "Jazz" Artist-Title.mp3' | | mp3info -t "T1 T2" -a "A1 A2" -g "Jazz" Artist-Title.mp3 | | echo 'Confirming: mp3info Artist-Title.mp3' | | mp3info Artist-Title.mp3 | |exit 0 | |$ ./tst9 |Resetting: mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3 |Artist-Title.mp3 does not have an ID3 1.x tag. |Executing: mp3info -t "T1 T2" -a "A1 A2" -g "Jazz" Artist-Title.mp3 |Confirming: mp3info Artist-Title.mp3 |File: Artist-Title.mp3 |Title: T1 T2 Track: |Artist: A1 A2 |Album: Year: |Comment: Genre: Jazz [8] This does NOT work (or, anyway, it doesn't work like I think it should.): : |$ cat tst8 |#!/bin/bash | | echo 'Resetting: mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3' | | mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3 | | TAGS='-t "T1 T2" -a "A1 A2" -g Jazz' | | echo '$TAGS = :' $TAGS | | echo 'Executing: mp3info $TAGS Artist-Title.mp3' | | mp3info $TAGS Artist-Title.mp3 | | echo 'Confirming: mp3info Artist-Title.mp3' | | mp3info Artist-Title.mp3 | |exit 0 | |$ ./tst8 |Resetting: mp3info -d Artist-Title.mp3 ; mp3info Artist-Title.mp3 |Artist-Title.mp3 does not have an ID3 1.x tag. |$TAGS = : -t "T1 T2" -a "A1 A2" -g Jazz |Executing: mp3info $TAGS Artist-Title.mp3 |Error opening MP3: T2": No such file or directory |Error opening MP3: A2": No such file or directory |Confirming: mp3info Artist-Title.mp3 |File: Artist-Title.mp3 |Title: "T1 Track: |Artist: "A1 |Album: Year: |Comment: Genre: Jazz [8] Notice that the Title is set to ["T1 ] and the Artist to ["A1 ], the leading double quote included. Notice that the { T2"} and { A2"} 'fragments' are seen as independent (bogus) parameters to `mp3info`. I'm probably using some wrong-headed thinking on this. Could someone please straighten me out? Thanks, Jonesy -- Marvin L Jones | jonz | W3DHJ | linux 38.24N 104.55W | @ config.com | Jonesy | OS/2 * Killfiling google & XXXXbanter.com: jonz.net/ng.htm
From: Seebs on 26 Jul 2010 17:19 On 2010-07-26, Allodoxaphobia <knock_yourself_out(a)example.net> wrote: > | mp3info -t "T1 T2" -a "A1 A2" -g "Jazz" Artist-Title.mp3 Okay, you are clearly aware of needing the quotes here. > | TAGS='-t "T1 T2" -a "A1 A2" -g Jazz' And here you suffer. > |Error opening MP3: T2": No such file or directory What's biting you is something maybe non-obvious. When you expand $TAGS, you do indeed get the string <-t "T1 T2" -a "A1 A2" -g Jazz> but! THOSE ARE NOT QUOTES. Those are plain ordinary characters with no special meaning which happen to be the same character as would be used for a quote, because nothing you expand from a variable has special meaning. One strategy: eval mp3info $TAGS ... But this may not be ideal. Basically, the thing that's biting you here is that you can't preserve the distinction between quoted and unquoted when you stash a string in a variable. There's a few ways to resolve this. What I usually use is take advantage of the positional parameters, because they have a magic thing: "$@". Basically, if you have two positional parameters, then "$@" is equivalent to "$1" "$2". And that means that you can start doing cool stuff, like: set -- "$@" -a "A1 A2" and this will append two arguments (-a, and "A1 A2") to the positional parameters, WITHOUT breaking quoting. And then you can do mp3info "$@" ... and the quoting and word breaks will be preserved. The thing that should have tipped you off to this was the reference to a file named <T2">, which suggests that the quotes became parts of words rather than magic metacharacters. Anyway, good luck, I'm not sure exactly what your inputs and outputs are intended to be, so it's not easy to suggest how to correctly do what you want. However, you do definitely deserve praise for submitting a well-crafted report of the problem. You showed us what you wanted, what you were trying, and what you got. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Chris F.A. Johnson on 26 Jul 2010 17:22 On 2010-07-26, Allodoxaphobia wrote: .... > | TAGS='-t "T1 T2" -a "A1 A2" -g Jazz' .... > | mp3info $TAGS Artist-Title.mp3 eval "mp3info $TAGS Artist-Title.mp3" -- Chris F.A. Johnson, author <http://shell.cfajohnson.com/> =================================================================== Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
From: Allodoxaphobia on 26 Jul 2010 18:46 On 26 Jul 2010 21:22:28 GMT, Chris F.A. Johnson wrote: > On 2010-07-26, Allodoxaphobia wrote: > ... >> | TAGS='-t "T1 T2" -a "A1 A2" -g Jazz' > ... >> | mp3info $TAGS Artist-Title.mp3 > > eval "mp3info $TAGS Artist-Title.mp3" Thank you, Chris -- and thanks, too, to Seebs. Having never used `eval` before, it just wasn't something that occurred to me. OK -- back to cutting code... Thanks! Jonesy -- Marvin L Jones | jonz | W3DHJ | linux 38.24N 104.55W | @ config.com | Jonesy | OS/2 * Killfiling google & XXXXbanter.com: jonz.net/ng.htm
From: Seebs on 26 Jul 2010 22:53
On 2010-07-27, Allodoxaphobia <knock_yourself_out(a)example.net> wrote: > Ahh, but... My "A1 A2" is a (required-to-be) quoted string containing > (usually) more than one 'word'. Yes. That is preserved. What you really need is an argument containing a space. Quotes are just one way of getting the space there. > "and the quoting ... will be preserved." ??? Yes. > |$ set -- "$@" -a "A1 A2" > |$ echo "$@" > |-a A1 A2 > > I need <-a "A1 A2"> --- I need the quoted |A1 A2| string. You have it. The quotes were eaten by the shell when it passed to echo, but you really did call echo with only two arguments: -a A1 A2 which is what you need. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated! |