LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   echo escape character weirdness (https://www.linuxquestions.org/questions/programming-9/echo-escape-character-weirdness-584550/)

insecurityman 09-13-2007 09:02 PM

echo escape character weirdness
 
I've been working on my first bash script of any complexity - a wrapper script for Wine - and I've been doing okay except for one baffling issue with echo, of all things. The problem comes up in the following command, which I use to strip Wine application command line arguments:
Code:

WINECOMMAND=`echo $@ | grep -o -i ".*\(exe\|bin\|msi\)"`
The odd thing about this is that echo, when run from the script, acts as though its been executed with the -e command-line option, meaning that when given the command
Code:

"C:\Program Files\Interplay\Fallout\falloutw.exe"
it interprets the \f as a carriage return and turns it into
Code:

"C:\Program Files\Interplay\Fallout
                                  alloutw.exe"

Stranger still, when I try it in a bash shell it executes as it should.

This is on Ubuntu Gutsy, and this is a /bin/sh script - is this a dash issue? Would converting the script to /bin/bash clear things up? Or am I just missing something blatantly obvious?

(The entire script can be found in this thread, by the way)

Thanks for any help!

JZL240I-U 09-14-2007 03:16 AM

Did you try it with backticks <'> or <`>instead of <">?

Btw. #!/bin/sh is used for portability, if you have bash anyhow and use the script only on that machine just change it as you suggested yourself, maybe you'll find the causation later...

firstfire 09-14-2007 02:25 PM

Hi!

Yes, this is a `dash' issue.
I tried to run following script
Code:

line="C:\Program Files\Interplay\Fallout\falloutw.exe"
WINECOMMAND=`echo -E $line | grep -o -i ".*\(exe\|bin\|msi\)"`

echo -E "$line"
echo -E "$WINECOMMAND"

through `bash' and `dash' interpreters. Here are the results:
Code:

$ bash escape.sh
C:\Program Files\Interplay\Fallout\falloutw.exe
C:\Program Files\Interplay\Fallout\falloutw.exe
$ dash escape.sh
-E C:\Program Files\Interplay\Fallout
                                    alloutw.exe
-E -E C:\Program Files\Interplay\Fallout
                                        alloutw.exe

As you can see, `dash' did not interpret the `-E' option of echo (don't interpret backslash sequences) as an option.

You can use something like this:
Code:

ECHO='/bin/echo -E'
line="C:\Program Files\Interplay\Fallout\falloutw.exe"
WINECOMMAND=`$ECHO $line | grep -o -i ".*\(exe\|bin\|msi\)"`

$ECHO "$line"
$ECHO "$WINECOMMAND"

... or use bash.

cfaj 09-15-2007 02:54 AM

Quote:

Originally Posted by insecurityman (Post 2891251)
I've been working on my first bash script of any complexity - a wrapper script for Wine - and I've been doing okay except for one baffling issue with echo, of all things. The problem comes up in the following command, which I use to strip Wine application command line arguments:
Code:

WINECOMMAND=`echo $@ | grep -o -i ".*\(exe\|bin\|msi\)"`


Use printf rather than echo for both reliability and portability:

Code:

printf "%s\n" "$*\n" | grep ...
Quote:

The odd thing about this is that echo, when run from the script, acts as though its been executed with the -e command-line option, meaning that when given the command
Code:

"C:\Program Files\Interplay\Fallout\falloutw.exe"
it interprets the \f as a carriage return and turns it into
Code:

"C:\Program Files\Interplay\Fallout
                                  alloutw.exe"



Dash adheres pretty closely to the POSIX/XSI standard, which says that echo shall interpret certain escape sequences rather than render them literally.
Quote:

Stranger still, when I try it in a bash shell it executes as it should.

Bash has a number of non-POSIX extensions.
Quote:

This is on Ubuntu Gutsy, and this is a /bin/sh script - is this a dash issue? Would converting the script to /bin/bash clear things up? Or am I just missing something blatantly obvious?

For portability, stick to POSIX syntax.

insecurityman 09-17-2007 08:58 PM

Thanks, all of you - that was really informative. This whole learning bash things is surprisingly fun.

I ended up converting the script over to bash, but the next thing I'll do is convert it back before I start getting too used to bashisms. I'll also start using printf instead of echo - I vaguely remember that issue being brought up in a few C tutorials I did a while back, but I didn't think to apply it here.

Thanks once more.

JZL240I-U 09-18-2007 01:42 AM

In case you don't know it already:

http://www.tldp.org/guides.html#abs

and for variety's sake

http://zsh.sunsite.dk/Guide/zshguide.html

archtoad6 09-23-2007 02:33 PM

Unless you need it for portability, I would use egrep instead of grep. I would also enclose the regex in single, rather than double, quotes:
Code:

| egrep -oi '.*(exe|bin|msi)'
I also suspect that your regex isn't selective enough -- that at the very least you need to check for a dot before the file type:
Code:

| egrep -oi '.*\.(exe|bin|msi)'

insecurityman,
Is this the right link?
http://ubuntuforums.org/showthread.php?t=533257
I can't seem find your script there. Maybe your Ubuntu forum name & the post# would help.

Arfyness 10-20-2008 04:20 AM

Call the executable directly.
 
This is from ages ago, but it's a good question and it's not solved here.

Quote:

Originally Posted by insecurityman (Post 2891251)

Stranger still, when I try it in a bash shell it executes as it should.

This is on Ubuntu Gutsy, and this is a /bin/sh script - is this a dash issue? Would converting the script to /bin/bash clear things up? Or am I just missing something blatantly obvious?

(The entire script can be found in this thread, by the way)

Thanks for any help!

This is common. Especially for something like 'echo'.

You'll find that most shells have an internal version of very simple commands, like ls, echo, pwd, cd, mkdir, etc... I bet you my paycheck* that you can solve this problem by replacing "echo" in your script with "/bin/echo" to call that binary instead of the shell builtin.

That will ensure that the 'echo' you call is the one described in the manpage.

* disclaimer, I'm currently unemployed.

-Arfy


All times are GMT -5. The time now is 04:12 AM.