7

I want to echo a string that might contain the same parameters as echo. How can I do it without modifying the string?

For instance:

$ var="-e something"
$ echo $var
something

... didn't print -e

kenorb
  • 155,785
  • 88
  • 678
  • 743
Ricky Robinson
  • 21,798
  • 42
  • 129
  • 185

6 Answers6

9

A surprisingly deep question. Since you tagged , I'll assume you mean bash's internal echo command, though the GNU coreutils' standalone echo command probably works similarly enough.

The gist of it is: if you really need to use echo (which would be surprising, but that's the way the question is written by now), it all depends on what exactly your string can contain.

The easy case: -e plus non-empty string

In that case, all you need to do is quote the variable before passing it to echo.

$ var="-e something"
$ echo "$var"
-e something

If the string isn't eaxctly an echo option or combination, which includes any non-option suffix, it won't be recognized as such by echo and will be printed out.

Harder: string can be -e only

If your case can reduce to just "-e", it gets trickier. One way to do it would be:

$ echo -e '\055e'
-e

(escaping the dash so it doesn't get interpreted as an option but as on octal sequence)

That's rewriting the string. It can be done automatically and non-destructively, so it feels acceptable:

$ var="-e something"
$ echo -e ${var/#-/\\055}
-e something

You noticed I'm actually using the -e option to interpret an octal sequence, so it won't work if you intended to echo -E. It will work for other options, though.

The right way

Seriously, you're not restricted to echo, are you?

printf '%s\n' "$var"
JB.
  • 40,344
  • 12
  • 79
  • 106
  • Thanks for the very detailed answer! I have a question: what's the difference between the two versions of echo that you mentioned? I'm on ubuntu. How do I launch them? – Ricky Robinson Nov 15 '13 at 16:07
  • 1
    If you're under bash, plain `echo` will get you the shell builtin, and `/usr/bin/echo` will get you the independent one. (There are other ways) You can tell them apart with `--version`. – JB. Nov 15 '13 at 16:38
  • This answer ignores that even the bash built-in echo implementation isn't guaranteed to behave consistently. Compare its behavior with and without `shopt -s xpg_echo; set -o posix` (and note that the former -- making bash's `echo` POSIX-compliant when the shell is otherwise in POSIX mode -- can be enabled-by-default as a compile-time flag). – Charles Duffy Aug 14 '17 at 20:13
  • It sure does. In all blunt honesty, the question wouldn't warrant it. – JB. Sep 06 '17 at 21:06
3

Quote it:

$ var="-e something"
$ echo "$var"
-e something

If what you want is to get echo -e's behaviour (enable interpretation of backslash escapes), then you have to leave the $var reference without quotes:

$ var="hi\nho"
$ echo $var
hi
ho

Or use eval:

$ var="hi\nho"
$ eval echo \${var}
hi\nho

$ var="-e hi\nho"
$ eval echo \${var}
hi
ho
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • I'd be curious about how you'd use `eval` to echo only "-e". – JB. Nov 15 '13 at 14:48
  • @JB. I also was... and kept testing a little bit. Just updated to show it :) – fedorqui Nov 15 '13 at 14:49
  • But... that still doesn't print "-e"! – JB. Nov 15 '13 at 14:49
  • To write the `-e` I use the first solution. If want I want is the `echo -e` behaviour, I use `eval`. I don't know what is the real OP question, one or the other :) – fedorqui Nov 15 '13 at 14:50
  • *My* question would be: can you get `echo` to print the string "-e" and "-e" only? – JB. Nov 15 '13 at 14:52
  • JB: Why would it print `-e` if the variable contains `-e something` (or why would you want that)? Your question doesn't make sense (but I'm sure I misunderstand you ;-) ). – Adrian Frühwirth Nov 15 '13 at 14:52
  • @AdrianFrühwirth imagine the variable contains "-e" only, if that makes more sense to you. As to why one would want that, all bets are off. – JB. Nov 15 '13 at 14:54
  • @JB Ah! You would use `printf` (see also [here (Application Usage)](http://pubs.opengroup.org/onlinepubs/007904875/utilities/echo.html)). – Adrian Frühwirth Nov 15 '13 at 14:56
3

The proper bash way is to use printf:

printf "%s\n" "$var"

By the way, your echo didn't work because when you run:

var="-e something"
echo $var

(without quoting $var), echo will see two arguments: -e and something. Because when echo meets -e as its first argument, it considers it's an option (this is also true for -n and -E), and so processes it as such. If you had quoted var, as shown in other answers, it would have worked.

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
2

Since we're using bash, another alternative to echo is to simply cat a "here string":

$ var="-e something"
$ cat <<< "$var"
-e something
$ var="-e"
$ cat <<< "$var"
-e
$ 

printf-based solutions will almost certainly be more portable though.

Digital Trauma
  • 15,475
  • 3
  • 51
  • 83
2

Try the following:

$ env POSIXLY_CORRECT=1 echo -e
-e

Due to shell aliases and built-in echo command, using an unadorned echo interactively or in a script may get you different functionality than that described here. Invoke it via env (i.e., env echo ...) to avoid interference from the shell.

The environment variable POSIXLY_CORRECT was introduced to allow the user to force the standards-compliant behaviour. See: POSIX at Wikipedia.

Or use printf:

$ printf '%s\n' "$var"

Source: Why is bash swallowing -e in the front of an array at stackoverflow SE

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • 1
    Better written as: `env POSIXLY_CORRECT=1 echo -e`. This doesn't use the builtin command, but the external command. Since it's very likely at `/bin/echo`, you might as well just call it so: `POSIXLY_CORRECT=1 /bin/echo -e`. But your `printf` solution is of course the best and the most portable. – gniourf_gniourf Mar 01 '15 at 14:23
1

Use printf instead:

var="-e bla"
printf "%s\n" "$var"

Using just echo "$var" will still fail if var contains just a -e or similar. If you need to be able to print that as well, use printf.

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • `bash` echo doesn't treat `--` specially; it just prints it as well. – chepner Nov 15 '13 at 14:46
  • I propose another version since I think it might be important to be able to print `-e` alone as well (which won't work with `echo` at all). – Alfe Nov 15 '13 at 14:51
  • Yeah, I was going to post a `printf`-based answer as well. I think that's the best solution. – chepner Nov 15 '13 at 15:13