636

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...
4
  • 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
    Commented Jun 25, 2012 at 16:41
  • 6
    on Ubuntu: echo -ne "text without new line: "; echo "some text";
    – zsoltii
    Commented Apr 26, 2016 at 9: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
    Commented Feb 17, 2020 at 8: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. Commented Jul 19, 2022 at 14:44

11 Answers 11

676

There are multiple versions of the echo command, with different behaviors. It's often built into the shell. If it isn't, echo will typically invoke /bin/echo or /usr/bin/echo, which itself can be from any of a number of implementations.

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?

13
  • 55
    By starting with the line #!/bin/bash it worked. Normally I'm working with bash.
    – qwertz
    Commented Jun 25, 2012 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. Commented Sep 24, 2016 at 6:57
  • 2
    @kayleeFrye_onDeck: Perhaps there's a Windows version of the printf command. Commented Sep 24, 2016 at 20:37
  • I wish. echo always adds newlines... The workaround is jenky at best. Commented Sep 26, 2016 at 17:58
  • 3
    @alper The % is your shell prompt. Try this, and watch carefully: printf hello; sleep 5 Commented May 12, 2020 at 21:21
186

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"
2
  • 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
    Commented Feb 11, 2021 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 apple.stackexchange.com/a/410266/157202 ... sh runs in POSIX compatibility mode. Commented Jul 19, 2022 at 14:42
104

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.

4
  • 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
    Commented Oct 19, 2016 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 Commented Oct 2, 2019 at 11:13
  • 1
    -e will not work in a posix shell script, it will be output to the screen instead. Commented Nov 11, 2019 at 21:11
  • -e is not needed in zsh. -n (no new line) works. Why not use zsh and leave the other shells?
    – Timo
    Commented Sep 2, 2020 at 5: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
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.

0
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"

2
enable -n echo
echo -n "Some string..."
1
  • 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, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today). Commented Nov 5, 2021 at 14:23
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

 ~
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.

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.
1
-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

Not the answer you're looking for? Browse other questions tagged or ask your own question.