我有
$>echo -n "\033[40m "
如果我在命令行上唤起它,将其保存到文件并在命令行上唤起文件,结果会有所不同。
我在mac上使用zsh,但希望这也适用于bash。输出不应该完全一样吗?如果没有,为什么?
答案 0 :(得分:4)
echo -n
的行为在shell之间是不同的(并且zsh和bash确实是不同的shell),因为它确实是未定义的行为:The POSIX sh specification不需要shell以任何特定的方式运行处理时:
应支持以下操作数:
string - 要写入标准输出的字符串。如果第一个操作数是
-n
,或者如果任何操作数包含反斜杠(\
)字符,则结果是实现定义的。
使用XSI扩展时,echo
需要处理反斜杠转义序列,如\033
,不再给出进一步的参数;没有这些扩展,根本不需要处理这些序列,而是纯粹是实现定义的行为(因此取决于您的特定shell)。
作为明确定义的替代方案,请考虑:
#!/bin/sh
# ^^ - because this code doesn't use any shell-specific extensions;
# use #!/bin/zsh if zsh-only, #!/bin/bash if bash-only, etc.
printf '%b' "\033[40m "
上述行为相同,无论是使用. yourscript
,./yourscript
,bash yourscript
,sh yourscript
还是zsh yourscript
调用,因为它完全由POSIX规范(并且不依赖于zsh选择破坏该规范的任何行为)。
如果您使用的是特定于shell的扩展,则需要使用./yourscript
调用(以便根据其内容选择shell来表示第一行),并使用. yourscript
仅使用相同的shell,或使用<shellname> yourscript
再次使用特定的shell。
出于这个原因,./yourscript
用法是首选,因为它允许脚本本身控制自己的解释器。
再次从POSIX echo
规范中引用,这次来自“应用程序使用”部分:
除非
-n
(作为第一个参数)和转义序列都被省略,否则不可能在所有POSIX系统中使用echo。
printf
实用程序可以移植来模拟echo
实用程序的任何传统行为,如下所示(假设IFS
具有其标准值或未设置):此系列IEEE Std 1003.1-2001中历史性的System V回声和对XSI实现的要求等同于:
printf "%b\n" "$*"
BSD回声相当于:
if [ "X$1" = "X-n" ] then shift printf "%s" "$*" else printf "%s\n" "$*" fi
鼓励新应用使用
printf
代替echo
。