633

I have a problem with echo in my script:

echo -n "Some string..."

prints

-n Some string...

and moves to the next line. In the console it's working correcly without newline:

Some string...
oguz ismail
  • 1
  • 16
  • 47
  • 69
qwertz
  • 14,614
  • 10
  • 34
  • 46
  • 2
    Which bourne shell implementation are you using? If I run `bash` in bourne shell mode, it works fine here. Also, it's somewhat unlikely you're really using a bourne shell as your interactive shell, no? – FatalError Jun 25 '12 at 16:41
  • 6
    on Ubuntu: `echo -ne "text without new line: "; echo "some text";` – zsoltii Apr 26 '16 at 09:01
  • I know this is very old, but this works for me in Windows 10, to add a period without a newline: echo | set /p="." – SPlatten Feb 17 '20 at 08:07
  • On MacOS (Monterey), I hit this on a script with `#!/usr/bin/env sh` at the top. Very curious since sh and bash both claim they are "GNU bash, version 3.2.57(1)-release (arm64-apple-darwin21)". But I proved it: `sh -c "echo -n"` prints `-n` whereas `bash -c "echo -n"` does not. – lmsurprenant Jul 19 '22 at 14:44

11 Answers11

673

There are multiple versions of the echo command, with different behaviors. Apparently the shell used for your script uses a version that doesn't recognize -n.

The printf command has much more consistent behavior. echo is fine for simple things like echo hello, but I suggest using printf for anything more complicated.

What system are you on, and what shell does your script use?

nullability
  • 10,545
  • 3
  • 45
  • 63
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 55
    By starting with the line `#!/bin/bash` it worked. Normally I'm working with bash. – qwertz Jun 25 '12 at 16:46
  • I wish there was a Windows equivalent in CMD :( As far as I can see, there isn't, just workarounds to achieve the same behavior. – kayleeFrye_onDeck Sep 24 '16 at 06:57
  • 2
    @kayleeFrye_onDeck: Perhaps there's a Windows version of the `printf` command. – Keith Thompson Sep 24 '16 at 20:37
  • I wish. `echo` always adds newlines... The workaround is jenky at best. – kayleeFrye_onDeck Sep 26 '16 at 17:58
  • @kayleeFrye_onDeckO Of course it's been asked before: http://stackoverflow.com/questions/5290074/bash-printf-equivalent-for-command-prompt – Keith Thompson Sep 26 '16 at 18:00
  • printf doing better than echo. – Muthukumar Anbalagan Jul 19 '17 at 18:25
  • `printf` shows `%` (`\0`) after each print, how can I supress it – alper May 12 '20 at 18:03
  • @alper Impossible to tell without knowing what arguments you passed to `printf`. Perhaps you should post a new question. – Keith Thompson May 12 '20 at 19:43
  • I was in zsh, and I just passed a string. `printf hello` but output is `hello%` – alper May 12 '20 at 20:08
  • 3
    @alper The `%` is your shell prompt. Try this, and watch carefully: `printf hello; sleep 5` – Keith Thompson May 12 '20 at 21:21
  • It's not necessarily the prompt; `zsh` has an option to display a particular character to indicate the absence of a newline, so that the prompt can be displayed on the following line in every case without confusion. – chepner Jun 18 '21 at 17:20
  • @chepner And if he had used that option, he wouldn't have seen `hello%`. If it's not the prompt, what else could it be? (BTW, what is that option?) – Keith Thompson Jun 18 '21 at 18:13
  • @KeithThompson. `PROMPT_SP` controls whether a partial line is preserved; `PROMPT_EOL_MARK` lets you change what `PROMPT_SP` displays, but the default is `%` for ordinary users and `#` for root users. (So it's related in some way to the prompt, but it's not just the prompt being displayed immediately after the output.) – chepner Jun 18 '21 at 18:24
185

bash has a "built-in" command called "echo":

$ type echo
echo is a shell builtin

Additionally, there is an "echo" command that is a proper executable (that is, the shell forks and execs /bin/echo, as opposed to interpreting echo and executing it):

$ ls -l /bin/echo
-rwxr-xr-x 1 root root 22856 Jul 21  2011 /bin/echo

The behavior of either echo's with respect to \c and -n varies. Your best bet is to use printf, which is available on four different *NIX flavors that I looked at:

$ printf "a line without trailing linefeed"
$ printf "a line with trailing linefeed\n"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
aqn
  • 2,542
  • 1
  • 16
  • 12
  • 1
    This is an important answer, because it helps to distinguish between echo as a command vs echo as an executable, which is not necessarily obvious when scripting. This means that if you really wanted to get the default behavior of the echo that you're used to, you can make sure you use the executable by using `/bin/echo -n` to get the no-newline display. `printf` may be a better option, but if you're used to using echo, you can still get the functionality you're expecting that way. – tobylaroni Feb 11 '21 at 15:52
  • 1
    On MacOS `/bin/bash` and `/bin/sh` are both bash (and thus use the builtin), but only the former supports the `-n` option. I found a nice explanation of that at https://apple.stackexchange.com/a/410266/157202 ... `sh` runs in POSIX compatibility mode. – lmsurprenant Jul 19 '22 at 14:42
103

Try with

echo -e "Some string...\c"

It works for me as expected (as I understood from your question).

Note that I got this information from the man page. The man page also notes the shell may have its own version of echo, and I am not sure if bash has its own version.

Sonny
  • 2,103
  • 1
  • 26
  • 34
  • 1
    +1 for hinting me to the right direction, though echo that does not recognise -ne option probably doesn't recognise -e (nor need) option either so you probably want to just say `echo "some string...\c"` instead. If however you need to support multiple bash variants with wildly differing echo commands you probably are better of using printf or you need to be checking the echo commands capabilities with something like `[ -n "$( echo -e )" ] && echo "sh stuff\c" || echo -e "bash stuff\c"` (at least bash supports \c as well, so no need to use the -n option, but you need the -e for bash) – Timo Oct 19 '16 at 10:26
  • To me, this does exactly what -n does in OP's case: outputs literal -e. I guess printf is indeed more consistent – ᴍᴇʜᴏᴠ Oct 02 '19 at 11:13
  • 1
    -e will not work in a posix shell script, it will be output to the screen instead. – Thomas Dignan Nov 11 '19 at 21:11
  • `-e` is not needed in `zsh`. `-n` (no new line) works. Why not use `zsh` and leave the other shells? – Timo Sep 02 '20 at 05:31
13

To achieve this there are basically two methods which I frequently use:

1. Using the cursor escape character (\c) with echo -e

Example :

for i in {0..10..2}; do
  echo -e "$i \c"              
done
# 0 2 4 6 8 10
  • -e flag enables the Escape characters in the string.
  • \c brings the Cursor back to the current line.

OR

2. Using the printf command

Example:

for ((i = 0; i < 5; ++i)); do
  printf "$i "
done
# 0 1 2 3 4
Deepam Gupta
  • 2,374
  • 1
  • 30
  • 33
3

If you use echo inside an if with other commands, like "read", it might ignore the setting and it will jump to a new line anyway.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

Just for the most popular Linux distribution, Ubuntu and its Bash:

  1. Check which shell are you using. Mostly the below works, else see this:

    echo $0

  2. If above prints bash, then the below will work:

    printf "hello with no new line printed at end"

    Or

    echo -n "hello with no new line printed at end"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
2

I believe right now your output prints as below

~ echo -e "String1\nString2"
String1
String2

You can use xargs to get multiline standard output into same line.

 ~ echo -e "String1\nString2" | xargs
String1 String2

 ~
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Raja G
  • 5,973
  • 14
  • 49
  • 82
2
enable -n echo
echo -n "Some string..."
  • An explanation would be in order. E.g., what is the idea/gist? What version of Bash was it tried on? On what operating system (incl. e.g. Linux distribution and version)? Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/60703359/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Nov 05 '21 at 14:23
1

Note that /usr/bin/echo and /bin/echo on AIX don't support any arguments, so neither -n nor -e work if using sh or KornShell (ksh) shells.

C shell and Bash have their own built-in echo which supports -n.
This is relevant, because a lot of shell scripts explicitly use sh or KornShell.

AIX does have /usr/bin/printf, so as suggested in some earlier answers,

$ printf "whatever"

is equivalent to echo -n "whatever" where -n is supported.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daemon42
  • 187
  • 2
  • 8
0

When you go and write your shell script, always use #!/usr/bin/env bash as the first line.

This shell doesn't omit or manipulate escape sequences.

Example:

echo "This is first \\n line"

prints

This is first \n line.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • An explanation for `#!/usr/bin/env bash` is in *[What is the difference between "#!/usr/bin/env bash" and "#!/usr/bin/bash"?](https://stackoverflow.com/questions/16365130/)*. – Peter Mortensen Nov 05 '21 at 14:20
-1

I had the same issue in IBM z/OS, so I used print instead of echo, and it worked.

print -n "Some string ...."

print — Return arguments from the shell

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Akhilesh
  • 542
  • 4
  • 7