Может быть интересно посмотреть значение переменной среды 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
Кстати, это показывает мой предпочтительный стиль использования одинарных кавычек для строки формата, чтобы указать, что в этом нет ничего лишнего (например, расширение параметра, которое вставляет дополнительный спецификатор формата, который не отражен в списке аргументов).