“echo -n”打印出"-n"。

634

我在脚本中使用 echo 函数遇到了问题:

echo -n "Some string..."
打印
-n Some string...

并移到下一行。在控制台中,它可以正常工作且没有换行符:

Some string...

2
你使用的是哪个 Bourne Shell 实现?如果我在 Bourne Shell 模式下运行 bash,它在这里可以正常工作。另外,你真的在使用 Bourne Shell 作为交互式 shell 的可能性不太大吧? - FatalError
6
在Ubuntu终端中输入以下命令:echo -ne "不换行的文本: "; echo "一些文本"; - zsoltii
我知道这很老,但在Windows 10中,以下命令适用于我,可以添加一个没有换行符的句号:echo | set /p="." - SPlatten
在MacOS(Monterey)上,我在一个以#!/usr/bin/env sh开头的脚本中遇到了这个问题。非常好奇,因为sh和bash都声称它们是“GNU bash,版本3.2.57(1)-release(arm64-apple-darwin21)”。但我证明了它:sh -c“echo -n”会打印出-n,而bash -c“echo -n”则不会。 - lmsurprenant
11个回答

674

有多个版本的echo命令,它们有不同的行为。 显然,您脚本所使用的 shell 使用了一个不认识 -n 的版本。

printf 命令具有更加一致的行为。 对于像 echo hello 这样简单的内容,echo 是可以使用的,但是对于任何更复杂的内容,我建议使用 printf

您使用的是什么系统,您的脚本使用的是哪个 shell?


55
通过以#!/bin/bash开头,这样做就成功了。通常我使用bash。 - qwertz
2
@kayleeFrye_onDeck:也许有一个Windows版本的printf命令。 - Keith Thompson
printf 比 echo 更好。 - Muthukumar Anbalagan
3
@alper 中的%是您的shell提示符。尝试这个命令,并仔细观察:printf hello; sleep 5 - Keith Thompson
这并不一定是提示符的问题;zsh有一个选项可以显示特定字符来指示换行符的缺失,以便在任何情况下都可以在下一行显示提示符而不会混淆。 - chepner
显示剩余8条评论

185

bash 有一个称为“echo”的内置命令:

$ type echo
echo is a shell builtin

另外,还有一个“echo”命令,它是一个正确的可执行文件(也就是说,Shell将分叉并执行/bin/echo,而不是解释echo然后执行它):

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

echo 命令在使用 \c-n 参数时的行为不同。建议使用 printf 命令,因为在我查看的四种 *NIX 系统中都有该命令:

$ printf "a line without trailing linefeed"
$ printf "a line with trailing linefeed\n"

1
这是一个重要的答案,因为它有助于区分echo作为命令和echo作为可执行文件之间的区别,在脚本编写时这并不明显。这意味着如果你真的想要得到你习惯的echo的默认行为,你可以通过使用/bin/echo -n来确保使用可执行文件以获取无换行显示。printf可能是一个更好的选择,但如果你习惯使用echo,你仍然可以通过这种方式获得你期望的功能。 - tobylaroni
1
在 MacOS 上,/bin/bash/bin/sh 都是 bash(因此使用内置命令),但只有前者支持 -n 选项。我在 https://apple.stackexchange.com/a/410266/157202 找到了一个很好的解释... sh 在 POSIX 兼容模式下运行。 - lmsurprenant

103

尝试使用

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

根据我的理解,这对我起到了预期的效果。

请注意,我从man页面获取了这些信息。 man页面还指出,shell可能有自己的版本echo,而我不确定bash是否有自己的版本。


1
+1 感谢你指引我正确的方向,尽管 echo 命令可能不认识 -ne 选项,但它很可能也不需要 -e 选项。因此,你可能只需要使用 echo "一些字符串...\c"。然而,如果你需要支持多个具有完全不同的 echo 命令的 bash 变体,那么最好使用 printf 命令,或者你需要使用类似 [ -n "$( echo -e )" ] && echo "sh stuff\c" || echo -e "bash stuff\c" 的命令来检查 echo 命令的功能(至少 bash 也支持 \c,所以不需要使用 -n 选项,但是你需要在 bash 中使用 -e 选项)。 - Timo
对我来说,这与 OP 的情况下的 -n 命令完全相同:输出文字 -e。我猜 printf 确实更加一致。 - ᴍᴇʜᴏᴠ
1
在 POSIX shell 脚本中,-e 不起作用,它将被输出到屏幕上。 - Thomas Dignan
zsh 中不需要使用 -e。可以使用 -n(无新行)选项。为什么不使用 zsh 并离开其他 shell 呢? - Timo

13

为了实现这一点,基本上有两种方法我经常使用:

1. 使用游标转义字符(\c)和echo -e命令

示例

for i in {0..10..2}; do
  echo -e "$i \c"              
done
# 0 2 4 6 8 10
  • -e标志启用了字符串中的E转义字符。
  • \cC光标带回当前行。

或者

2.使用printf命令

示例:

for ((i = 0; i < 5; ++i)); do
  printf "$i "
done
# 0 1 2 3 4

3

仅适用于最受欢迎的Linux发行版Ubuntu和它的Bash:

  1. 检查您正在使用哪个shell。大多数情况下以下命令有效,否则参见此处

    echo $0

  2. 如果上述命令打印bash,则以下命令有效:

    printf "hello with no new line printed at end"

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


3

如果你在一个带有其他命令的if语句中使用echo,比如“read”,它可能会忽略设置并且会跳到一个新的行。


2
我相信您现在的输出如下所示。
~ echo -e "String1\nString2"
String1
String2

你可以使用xargs将多行标准输出合并到同一行。
 ~ echo -e "String1\nString2" | xargs
String1 String2

 ~

2
enable -n echo
echo -n "Some string..."

需要解释一下。例如,这个想法/主旨是什么?尝试了哪个版本的Bash?在哪个操作系统上(包括Linux发行版和版本)?请通过编辑(更改)您的答案来回复,而不是在评论中回复(不要添加“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天写的)。 - Peter Mortensen

1
请注意,在AIX上,/usr/bin/echo/bin/echo不支持任何参数,因此如果使用sh或KornShellksh)shell,则-n-e都无法使用。 C shellBash都有自己内置的echo,支持-n。这很重要,因为很多shell脚本明确使用sh或KornShell。
AIX确实有/usr/bin/printf,因此建议使用一些早期答案中提到的方法。
$ printf "whatever"

这相当于echo -n "whatever",其中-n受支持。


0

当你编写Shell脚本时,请始终使用#!/usr/bin/env bash作为第一行。

这个shell不会省略或操纵转义序列。

示例:

echo "This is first \\n line"

打印

This is first \n line.

#!/usr/bin/env bash 的解释可以在 “#!/usr/bin/env bash”和“#!/usr/bin/bash”有什么区别?” 中找到。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接