Ambiguos Redirect Error

I have the below lines of code.

ls found*.tmp | while IFS= read -r entry; do
APP_NAME=$(sed -n -e 's/^.*<name>//' -e 's|</name>.*$||'p $entry | sed 's/\(<name>\|<\/name>\)//g')
echo "APP_NAME="$APP_NAME>$APP_NAME"_Deploy.cfg"
done

I m getting the below error while running the above script.

bash-3.2$ ./test.sh
./test.sh: line 7: $APP_NAME"_Deploy.cfg": ambiguous redirect
./test.sh: line 7: $APP_NAME"_Deploy.cfg": ambiguous redirect
./test: line 7: $APP_NAME"_Deploy.cfg": ambiguous redirect
./test: line 7: $APP_NAME"_Deploy.cfg": ambiguous redirect

I tried this echo "APP_NAME="$APP_NAME>"{$APP_NAME}"_Deploy.cfg

This time i did not get the error but the .cfg files were not generated when they should.

uname -a SunOS mymac 5.10 Generic_150400-23 sun4v sparc sun4v

Can you please help fix this.

Your code snippet doesn't have 7 lines, so I'd be inclined to look for the error somewhere else! Why don't you post the entire script?

In line 3 of your snippet, you seem to want to redirect echo 's output to $APP_NAME"_Deploy.cfg" . What's this string after expansion?

It is line 3 that is throwing the error instead of line 7 asthe preceding lines in my script are comments.

i am trying to append "_Deploy.cfg" to the filename after $APP_NAME variable.

So if $APP_NAME is "flipkart" my filename should be flipkart_Deploy.cfg

You can use my code snippet to replicate the error on Solaris.

What's above string after variable's expansion?

These lines are completely bogus anyways, there is little sense in debugging them.

You are doing a

ls found*.tmp | while IFS= read -r entry; do
   [...something...]
done

and my suspicion is that you want to read the contents of all files named "found*.tmp" mince that through your while-loop. What you do in fact is to expand "found*.tmp", which will give you a list of files, something like

found1.tmp found2.tmp found3.tmp foundfoo.tmp [...]

then you present this list to "ls", which will do nothing more than list it (again), resulting in this list:

found1.tmp
found2.tmp
found3.tmp
foundfoo.tmp
[...]

Notice that the only thing "ls" has done for you is to convert the separating spaces to linefeeds. Now, you take one after the other of these filenames and present them to sed , as input files, one after the other and every time you invoke sed in a separate subshell.

May i ask you a personal question: if you go to a chinese restaurant, do you call the waiter separately for each order of a single grain of rice or do you call him once and tell him to bring "the big rice plate, with everything on it"? Because this is like you treat poor old sed in your script: instead of presenting it a single stream to work on you call it once every time you got some characters to process.

Here is how you can do the same in perhaps a fraction of the time:

cat found*tmp | sed -n 's/.*<name>/;s/<\/name>.*/_Deploy.cfg/p'

This line will have the same limitations your original would have had, if you would have written it syntactically correct: it will only work correctly if there is only one "<name>...</name>" tag pair on every single line of input and none of these pairs span more than one line. Also, the script takes no caution for superfluous spaces. The following lines anywhere in your input will make the commands output probably not what it is intended to be and/or unusable (just like your script, would it have been correct):

<name>foo</name> foo <name>bar</name>
<name>foo
</name>
<name>  foo  </name>
<name>foo</ name>

I hope this helps.

bakunin

2 Likes