echo -e在ubuntu上由root运行在脚本中时的行为不同

时间:2010-05-28 19:18:04

标签: bash ubuntu scripting echo

在ubuntu 9.10上运行bash脚本时,我会从bash echo的“-e”选项中获得不同的行为,具体取决于我是否以root身份运行。

考虑这个脚本:

$ cat echo-test
if [ "`whoami`" = "root" ]; then
  echo "Running as root" 
fi
echo Testing /bin/echo -e
/bin/echo -e "foo\nbar"
echo Testing bash echo -e
echo -e "foo\nbar"

以非root用户身份运行时,我会看到此输出:

$ ./echo-test 
Testing /bin/echo -e
foo
bar
Testing bash echo -e
foo
bar

以root身份运行时,我看到了这个输出:

$ sudo ./echo-test 
Running as root
Testing /bin/echo -e
foo
bar
Testing bash echo -e
-e foo
bar

注意在最后一种情况下回显“-e”(“-e foo”而不是倒数第二行的“foo”)。以root身份运行脚本时,echo命令的运行就像给出“-e”一样,如果给出了-e,则回显选项本身。

我可以理解/ bin / echo和bash echo之间行为的一些细微差别,但无论用户调用它,我都希望bash echo的行为相同。

任何人都知道为什么会这样吗?这是bash echo中的错误吗?

仅供参考 - 我正在运行GNU bash,版本4.0.33(1)-release(x86_64-pc-linux-gnu)

3 个答案:

答案 0 :(得分:4)

你确定你的用户和root都使用bash作为他们的shell吗? 尝试在脚本中添加“shebang”行(#!/ bin / bash)作为第一行,然后再次运行

答案 1 :(得分:1)

看到POSIXLY_CORRECT环境变量的值并确定是否在两种情况下都启用了xpg_echo shell选项可能会很有趣。

if test -n "${POSIXLY_CORRECT+yes}"; then
    pc="set '$POSIXLY_CORRECT'"
else
    pc=unset
fi
echo POSIXLY_CORRECT: "$pc"
shopt -q xpg_echo && xe=set || xe=unset
echo xpg_echo: $xe

以下是我用来检查各种组合的测试代码:

{ n=1
for p in '' p; do
    for x in '' x; do
        for e in '' e; do
            printf "\nmode: ${p:-_}${x:-_}${e:-_}\n"
            test -n "$x" && xx=-s || xx=-u
            bash ${p:+--posix} -c "              shopt $xx xpg_echo
              test -n \"\${POSIXLY_CORRECT+yes}\" && pc=\"set '\$POSIXLY_CORRECT'\" || pc=unset
              shopt -q xpg_echo && xe=set || xe=unset
              echo POSIXLY_CORRECT: \"\$pc\"
              echo xpg_echo: \$xe
              echo${e:+ -e} \"$n\n$((n+1))\"
            "
            n=$((n+2))
        done
    done
done
}

在我的系统上,你的“as root”效果会在最后一种情况下重现(POSIXLY_CORRECT和xpg_echo都已设置)。

mode: ___
POSIXLY_CORRECT: unset
xpg_echo: unset
1\n2

mode: __e
POSIXLY_CORRECT: unset
xpg_echo: unset
3
4

mode: _x_
POSIXLY_CORRECT: unset
xpg_echo: set
5
6

mode: _xe
POSIXLY_CORRECT: unset
xpg_echo: set
7
8

mode: p__
POSIXLY_CORRECT: set 'y'
xpg_echo: unset
9\n10

mode: p_e
POSIXLY_CORRECT: set 'y'
xpg_echo: unset
11
12

mode: px_
POSIXLY_CORRECT: set 'y'
xpg_echo: set
13
14

mode: pxe
POSIXLY_CORRECT: set 'y'
xpg_echo: set
-e 15
16

行为的这些变化是提倡 printf 而不是 echo 的主要原因。

根据系统和shell,有时 printf 是一个shell内置命令,有时候它是一个外部命令,但它的行为通常比 echo <更加一致/ em>的

您可以确定以下每个命令都会生成嵌入式换行符,而不会生成尾随换行符:

printf 'foo\nbar'
printf '%s\n%s' foo bar

顺便说一下,这显示了我使用格式字符串的单引号的首选样式,表示没有任何时髦的内容(例如,插入额外格式说明符的参数扩展未反映在参数列表中)。

答案 2 :(得分:0)

Ubuntu 9.10以后使用dash作为默认shell,而不是bash。

Dash可以被认为是bash的轻量级替代品,但它有一些轻微的不兼容性。您应该通过“Shebang”符号

明确指定bash