Как мне напечатать '-e' с помощью echo?

8

Я знаю, что echo -eэто не обычная команда. Я попробовал echo '-e'и , echo \-eно они до сих пор не `т работы.

Основные заводские
источник
1
Что вы имеете в виду под «необычной командной строкой»? echoобычно встроен в оболочку, но обычно есть и /usr/bin/echo. Это -eне POSIX, но доступно, например, с bash. Пожалуйста, опишите подробнее, что вы имеете в виду под словом «они все еще не работают». Какое поведение ожидается?
maxschlepzig
Я хочу напечатать -e с помощью эха. Какие-либо предложения?
Основные события завода
3
рассмотрите использование printf, это более переносимо.
Майкл Даррант
1
Как ни странно, echo -- -eтоже не работает. Традиционно (по крайней мере, с утилитами GNU) двойная черта указывает на конец опций, а остальные остаются в качестве буквальных аргументов.
Уил Кули
6
echoопять безумие Если бы люди только использовали printfи никогда не оглядывались назад.
Йенс

Ответы:

9
  • с новой строкой

    echo -en '-e\n'
  • без перевода строки

    echo -e '-e\c'
  • с пробелами вокруг:

    echo '-e '
    echo ' -e'
    
  • используя backspace (спасибо Джозефу Р.):

    echo -e ' \b-e'

    (он выводит SPC BS - e LF, но при отправке на терминал, который отображается -eкак BS, перемещает курсор назад на один столбец влево, вызывая -перезапись SPC)

Поведение bash«S echoвстроенной команды может зависеть от Баш версии. Это также зависит от окружающей среды ( POSIXLY_CORRECT, SHELLOPTSи BASHOPTSпеременные), параметры ( posix, xpg_echo), варианты сборки и argv[0]( shVS bash). Здесь протестировано с GNU bash 4.2.53(1), сборкой по умолчанию, опциями по умолчанию, пустой средой, вызываемой как bash. Работает также с zsh 5.0.5.

jimmij
источник
+1 Такжеecho -e 'x\b-e'
Джозеф Р.
2
Почему эти "уродливые" до костей "обходные пути" получают отрицательные отзывы? Чарльз Даффи ниже дает правильный ответ: используйте printf и забудьте о таких проблемах раз и навсегда.
Йенс
7
Йенс: потому что ОП спросил, как это сделать с помощью echoкоманды. Отношение не обязательно.
ctc
1
echo -e ' \b-e'выводит space-backspace-dash-e. Только отображенный в терминале, он создаст иллюзию, что это dash-e.
Стефан Шазелас
1
@CharlesDuffy, echo -e "\0-e"выводит NUL-dash-e. Это просто , что терминалы игнорируют , что NUL символы (NULs даже используется для отправки некоторых терминалов (которые не поддерживают управление потоком) , чтобы дать им время , чтобы делать другие длинные вещи , как возврат каретки. Смотрите раздел под Задержкой и отступов в terminfo(5).)
Стефан Шазелас
25

Лучшее решение - не использовать echo, а использовать printfвместо этого.

printf '%s\n' -e

Это работает с произвольными переменными:

var=-e
printf '%s\n' "$var"

... то есть вам не нужно выполнять какую-либо специальную подготовку / модификацию в другом месте вашего кода, основываясь на знании того, что значение будет echod.


Кстати, спецификация команды оболочки POSIXecho подтверждает, что она непереносима при ее реализации, и содержит примечание на эту тему:

Невозможно использовать echo переносимо во всех системах POSIX, если не опущены как -n (в качестве первого аргумента), так и escape-последовательности.

Утилита printf может использоваться переносимо для эмуляции любого традиционного поведения утилиты echo следующим образом (при условии, что IFS имеет свое стандартное значение или не установлено):

Исторический эхо System V и требования к реализациям XSI в этом томе POSIX.1-2008 эквивалентны:

printf "%b\n" "$*"

Эхо BSD эквивалентно:

if [ "X$1" = "X-n" ]
then
    shift
    printf "%s" "$*"
else
    printf "%s\n" "$*"
fi

В новых приложениях рекомендуется использовать printf вместо echo.

(Акцент добавлен).


Тем не менее, в системах GNU существует альтернатива: запрос поведения, соответствующего стандартам.

$ POSIXLY_CORRECT=1 /bin/echo -e
-e
Чарльз Даффи
источник
Интересно, что в заметке POSIX говорится, что echo -eона портативна. Это говорит о том, что -nследует избегать и избегать последовательностей побега. echo -eизбегает обоих. Но, как вы указали в последней части вашего ответа, в системах GNU echoне заботится о том, чтобы по умолчанию вообще соответствовать POSIX, а POSIX отмечает только переносимость между системами POSIX.
HVd
@hvd, я не вижу -eв той части спецификации, с которой я связан. Не могли бы вы предоставить ссылку или цитату, которая покрывает это?
Чарльз Даффи
Это говорит об отсутствии упоминания. :) В нем перечислены виды использования, которые не являются переносимыми и -eне упоминаются, а также -eпереносимы (опять же, для всех систем POSIX). Чтобы быть справедливым, то, что вы цитировали, является информативным, но нормативный текст говорит то же самое: «Если первый операнд -n или любой из операндов содержит символ <backslash>, результаты определяются реализацией».
апреля
2
@hvd, скорее наоборот. Чтобы выполнить как указано, echoнеобходимо выдать все аргументы без поведения, определенного стандартом противоположным образом. Таким образом - в отличие от почти всех других инструментов командной строки, охватываемых спецификацией POSIX, - echoфактически определяет поведение для аргументов, которые не приведены: их печать. Нет места для добавления новых флагов без нарушения спецификации.
Чарльз Даффи
2
@hvd, ... по этому вопросу см OPTIONSраздел, в котором он установлен в черно-белом: Implementations shall not support any options.
Чарльз Даффи
9

С GNU echo«S -eс ASCII - кодами символов:

$ /bin/echo -e '\055'e
-e

055является восьмеричным числом ASCII для -(см. man asciiкраткий справочник).

Мур
источник
1
/bin/echoдействительно определено POSIX. Однако его интерпретация восьмеричных escape-последовательностей является расширением XSI к базовой спецификации.
Чарльз Даффи,
@CharlesDuffy Действительно, я оговорился. +1 за принтф (моя первая мысль тоже). Однако, учитывая, что -eэто расширение, есть ли способ навязать поведение чистого POSIX echo? Я думаю, это устранило бы всю неуверенность в этом.
Муру
2
На самом деле да! Экспорт POSIXLY_CORRECT=1приведет к POSIX-совместимому поведению для GNU /bin/echo.
Чарльз Даффи
+1 Спасибо, полезно знать, чтобы ваши скрипты были переносимыми и «независимыми от homebrew-Linux» (т.е. также работали на профессиональной рабочей станции на работе).
синтаксическая ошибка
@Kusalananda забыл об этом.
Муру
3

Хотя очевидным, стандартным и рекомендуемым решением является использование printf, сделать это echoможет быть довольно сложно в зависимости от реализации (не так сложно, как -nкажется).

POSIX.2017 совместимый echoс

POSIX требует echo -e вывода -e<newline>. Так что это просто

echo -e

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

  • echoвстроенный в bashкогда оба xpg_echoи posixопции включены (во время выполнения или сборки время , как для /bin/shот Apple MacOS). set -o posix; shopt -s xpg_echo(эта posixопция также может быть включена, если она вызывается как shили когда POSIXLY_CORRECTили SHELLOPTS=posixнаходится в среде).
  • /bin/echoсертифицированных систем UNIX (AIX, MacOS, Solaris , по крайней мере) , и большинство BSDs
  • echoвстроенный из dash, ksh88, Борна оболочки, CSH, Tcsh, шикарном, RC, ES, akanga
  • GNU echo( /bin/echoв системах GNU), когда он POSIXLY_CORRECTнаходится в окружающей среде.
  • echoвстроенный в mkshи некоторые другие pdksh-производный , когда их posixвключена опция.
  • echoвстроенный из yashкогда $ECHO_STYLEлибо установлен или один из SYSV, XSI, BSD, DASH,RAW

реализации, которые поддерживают -e

Включает в echoисследовательской Unix V8 (где он выходит), GNU, BusyBox, с echoвстроенной командой из bash, zsh, pdkshи их производные, fishнекоторые ash-На оболочки , как BusyBox shили shнекоторых BSDs, последние версии ksh93(на некоторых системах, а также с некоторыми значениями $PATH) с настройками по умолчанию, yashс $ECHO_STYLEодним из GNUили ZSH:

echo -e '-e\n\c'

Реализации, которые поддерживают, -eвсегда поддерживают -n, поэтому:

echo -ne '-e\n'

будет работать так же.

ЗШ

zsh«S echoявляется единственной реализацией , что я знаю , что поддерживает истекший вариант маркеров ( -).

echo - -e

Делая это единственной подобной Борну оболочкой, echoкоторая может выводить произвольные данные (также потому, что она единственная, которая поддерживает байты NUL в своих переменных и аргументах своих встроенных функций) с помощью echo -E - "$data")

За исключением проблемы NUL-байтов, другими реализациями, которые могут выводить произвольные данные, являются FreeBSD или macOS, /bin/echoгде вы можете сделать:

/bin/echo "$data
\c"

(в этой реализации \cраспознается только в конце, и никакая другая escape-последовательность не поддерживается).

И yashs:

ECHO_STYLE=RAW echo "$data"

(хотя обратите внимание, что yashпеременные могут содержать только текст, поэтому не произвольные последовательности байтов в локалях, где не все последовательности байтов могут образовывать допустимые символы, как в тех, которые используют UTF-8 в качестве своей карты символов).

Стефан Шазелас
источник
2

Используйте, -nчтобы избежать новой строки:

$ echo -n - && echo e
-e
vishalknishad
источник
Это не сработает в том месте, zshгде -находится конец разделителя опций, или во всех echoреализациях, которые не поддерживают -n( хотя и те, которые -eподдерживают -n)
Стефан