简体   繁体   English

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

[英]echo -e acts differently when run in a script by root on ubuntu

When running a bash script on ubuntu 9.10, I get different behavior from bash echo's "-e" option depending on whether or not I'm running as root. 在ubuntu 9.10上运行bash脚本时,我会从bash echo的“-e”选项中获得不同的行为,具体取决于我是否以root身份运行。

Consider this script: 考虑这个脚本:

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

When run as non-root user, I see this output: 当以非root用户身份运行时,我看到此输出:

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

When run as root, I see this output: 以root身份运行时,我看到此输出:

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

Notice the "-e" being echoed in the last case ("-e foo" instead of "foo" on the second-to-last line). 注意“-e”在最后一种情况下被回显(“-e foo”而不是倒数第二行的“foo”)。 When running a script as root, the echo command runs as if "-e" was given and, if -e is given, the option itself is echoed. 以root身份运行脚本时,echo命令的运行就好像给出“-e”一样,如果给出-e,则回显选项本身。

I can understand some subtle differences in behavior between /bin/echo and bash echo, but I would expect bash echo to behave the same no matter which user invokes it. 我可以理解/ bin / echo和bash echo之间行为的一些细微差别,但我希望无论哪个用户调用它,bash echo的行为都是一样的。

Anyone know why this is the case? 任何人都知道为什么会这样吗? Is this a bug in bash echo? 这是bash echo中的一个错误吗?

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

are you sure that your user and root both use bash as their shell? 你确定你的用户和root都使用bash作为他们的shell吗? try putting a "shebang" line (#!/bin/bash) in your script as first line, and run it again 尝试在脚本中添加“shebang”行(#!/ bin / bash)作为第一行,然后再次运行

It might be interesting to see the value of POSIXLY_CORRECT environment variable and to determine whether xpg_echo shell option is enabled in both situations. 看到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

Here is the test code I used to examine the various combinations: 这是我用来检查各种组合的测试代码:

{ 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
}

On my system, your “as root” effect is reproduce in the last case (both POSIXLY_CORRECT and xpg_echo are set). 在我的系统上,你的“作为根”效果在最后一种情况下重现(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

These variations in the behavior are the primary reason the use of printf is advocated over echo . 这些行为的变化是主张使用printf而不是echo的主要原因。

Depending on the system and shell, sometimes printf is a shell built-in command and sometimes it is an external command, but its behavior is generally much more consistent than that of echo . 根据系统和shell的不同,有时printf是一个shell内置命令,有时它是一个外部命令,但它的行为通常比echo更加一致。

You can be sure that each of the following commands will produce an embedded newline and no trailing newline: 您可以确定以下每个命令都将生成嵌入式换行符,而不会生成尾随换行符:

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

BTW, this shows my preferred style of using single quotes for the format string to indicate that nothing funky is going into it (eg a parameter expansion that inserts an extra format specifier that is not reflected in the argument list). 顺便说一句,这显示了我使用格式字符串的单引号的首选样式,表示没有任何时髦的内容(例如,插入额外格式说明符的参数扩展,不会反映在参数列表中)。

Ubuntu 9.10 onward uses dash as default shell, instead of bash. Ubuntu 9.10以后使用dash作为默认shell而不是bash。

Dash can be consider a lightweight alternative of bash, but it has some minor incompatibility. Dash可以被认为是bash的轻量级替代品,但它有一些轻微的不兼容性。 You should specify bash explicitly by "Shebang" sign 您应该通过“Shebang”符号明确指定bash

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM