echo -e действует по-другому при запуске в скрипте пользователем root на ubuntu - PullRequest
3 голосов
/ 28 мая 2010

При запуске скрипта bash в Ubuntu 9.10 я получаю другое поведение от опции "-e" в bash echo в зависимости от того, запущен ли я от имени пользователя 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) -релиз (x86_64-pc-linux-gnu)

Ответы [ 3 ]

4 голосов
/ 28 мая 2010

Вы уверены, что ваш пользователь и root используют bash в качестве оболочки?попробуйте добавить строку «shebang» (#! / bin / bash) в ваш скрипт в качестве первой строки и запустите ее снова

1 голос
/ 29 мая 2010

Может быть интересно посмотреть значение переменной среды POSIXLY_CORRECT и определить, включена ли опция оболочки xpg_echo в обеих ситуациях.

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
}

В моей системе ваш «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 .

В зависимости от системы и оболочки, иногда printf является встроенной командой оболочки, а иногда - внешней командой, но ее поведение, как правило, гораздо более согласованно, чем у echo .

Вы можете быть уверены, что каждая из следующих команд создаст встроенную новую строку и не завершающую новую строку:

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

Кстати, это показывает мой предпочтительный стиль использования одинарных кавычек для строки формата, чтобы указать, что в этом нет ничего лишнего (например, расширение параметра, которое вставляет дополнительный спецификатор формата, который не отражен в списке аргументов).

0 голосов
/ 22 апреля 2012

Ubuntu 9.10 и выше использует dash в качестве оболочки по умолчанию вместо bash.

Тире можно считать легкой альтернативой bash, но она имеет небольшую несовместимость. Вы должны явно указать bash знаком "Шебанг"

...