tags:

views:

63

answers:

3

Hi, I write a sh script (test.sh) like this:

#!/bin/sh

echo $@

and then run it like this:

#./test.sh '["hello"]'

but the output is:

"

In fact I need

["hello"]

The bash version is:

#bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

And if I run

# echo '["hello"]'
["hello"]

I don't know why the script cannot work...

A: 

Just a guess, but maybe try changing the first line to

#!/bin/bash

so that it actually runs with bash?

David Zaslavsky
no, it still cannot work...
Jianzhong
+1  A: 

You probably mean "$@", though I don't think it should make much of a difference in this case. It's also worth making sure that the script is executable (chmod +x test.sh).

EDIT: Since you asked,

Bash has various levels of string expansion/manipulation/whatever. Variable expansion, such as $@, is one of them. Read man bash for more, but from what I can tell, Bash treats each command as one long string until the final stage of "word splitting" and "quote removal" where it's broken up into arguments.

This means, with your original definition, that ./test.sh "a b c d" is equivalent to echo "a" "b" "c" "d", not echo "a b c d". I'm not sure what other stages of expansion happen.

The whole word-splitting thing is common in UNIXland (and pretty much any command-line-backed build system), where you might define something like CFLAGS="-Os -std=c99 -Wall"; it's useful that $CFLAGS expands to "-Os" "-std=c99" "-Wall".

In other "$scripting" languages (Perl, and possibly PHP), $foo really means $foo.

tc.
Thanks, if i change $@ to "$@", it works. but i don't know why...
Jianzhong
I can't actually reproduce your bug though.
tc.
+1  A: 

The manual test you show works because echo gets the argument ["hello"]. The outermost quotes are stripped by the shell. When you put this in a shell script, each shell strips one layer of quotes: the one you type at and the one interpreting the script. Adding an extra layer of quotes makes that work out right.

Brian Sniffen