From: Allodoxaphobia on
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
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
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
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
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!