0

Using -e as a flag in a command bash file isn't recognized. Let's say we have a bash file named server.sh, which only echoes all the passed arguments:

server.sh

echo "$@"

Here are the results so far when server.sh is executed with an -e as a first argument:

./server.sh -e hello ## output: hello
./server.sh -eeeee world ## output: world
./server.sh -eeeeeeeeeeeee what ## output: what

Any other arguments are valid except for arguments that starts with an -e. Can anyone tell me the reason why this is happening? And is there a way to make the -e argument be recognized in server.sh?

ryeballar
  • 29,658
  • 10
  • 65
  • 74
  • 2
    I suggest to take a look at `help echo`. – Cyrus Jun 16 '17 at 18:36
  • 4
    `-e` is a flag to echo, which is one of the reasons you should use printf instead. Think some `echo`'s you can do `--`, but it isn't documented so is not reliable. – 123 Jun 16 '17 at 18:36
  • hope this will be useful, https://stackoverflow.com/questions/16483119/example-of-how-to-use-getopts-in-bash – dkb Jun 16 '17 at 18:45
  • check command: $man \`echo $0\` documentation, echo $0 give you which shell you are using and man shell gives documentation. – dkb Jun 16 '17 at 18:49
  • @dkb, `man echo` documents `/usr/bin/echo`, which is a separate command from the shell builtin named `echo`. The builtin is documented as part of the shell -- ie. in `man bash`, when using bash as the pertinent shebang. – Charles Duffy Jun 16 '17 at 19:10
  • `-e` is a flag to `echo`, in *some* implementations of echo, in *some* modes. Even if your shell is bash, if you set both `posix` and `xpg_echo` flags, then `-e` is no longer honored as anything other than content to be printed. Much more reliably to use `printf`, which is unambiguously specified. – Charles Duffy Jun 16 '17 at 19:19

1 Answers1

1

Here's an easier way to reproduce your problem:

$ echo "-e" "foo"
foo             # What happened to "-e"?

echo parsing your intended output as options is one of the reasons why POSIX warns against this command in portable scripts.

If you are trying to dump the parameters for logging and debugging purposes, you can use bash's printf %q:

 #!/bin/bash   
 # (does not work with sh)
 printf '%q ' "$0" "$@"
 printf '\n'

This will escape output the arguments in such a way that you can copy-paste it back to the shell to reproduce it later (quoting changes, but the arguments will be identical):

$ ./myscript -e -avx --arg "my long arg" '(!#%^)(!*'
./myscript -e -avx --arg my\ long\ arg \(\!#%\^\)\(\!\*

If you actually do want to write out the arguments separated by spaces in an ambiguous form, you can use:

#!/bin/sh
# works with bash and POSIX sh
printf '%s\n' "$*"

This results in:

$ ./myscript -e -avx --arg "my long arg" '(!#%^)(!*'
-e -avx --arg my long arg (!#%^)(!*
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Thanks, I already knew of echo -e, I just didn't think that it would be evaluated as an expression for -e to render. since the argument, `"$@"`, is wrapped inside a double quote. – ryeballar Jun 16 '17 at 19:07
  • 1
    @ryeballar, a command (including a builtin such as `echo`, except for special syntax such as `[[ ]]`) has no way of knowing which arguments to it were quoted and which ones weren't. By the time it's called, all it gets is an array of C strings; it can't tell how that array was formed. – Charles Duffy Jun 16 '17 at 19:08