Что вы имеете в виду под «необычной командной строкой»? 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.
Почему эти "уродливые" до костей "обходные пути" получают отрицательные отзывы? Чарльз Даффи ниже дает правильный ответ: используйте 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.
Невозможно использовать echo переносимо во всех системах POSIX, если не опущены как -n (в качестве первого аргумента), так и escape-последовательности.
Утилита printf может использоваться переносимо для эмуляции любого традиционного поведения утилиты echo следующим образом (при условии, что IFS имеет свое стандартное значение или не установлено):
Исторический эхо System V и требования к реализациям XSI в этом томе POSIX.1-2008 эквивалентны:
Интересно, что в заметке 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краткий справочник).
/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
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 в качестве своей карты символов).
Это не сработает в том месте, zshгде -находится конец разделителя опций, или во всех echoреализациях, которые не поддерживают -n( хотя и те, которые -eподдерживают -n)
echo
обычно встроен в оболочку, но обычно есть и/usr/bin/echo
. Это-e
не POSIX, но доступно, например, с bash. Пожалуйста, опишите подробнее, что вы имеете в виду под словом «они все еще не работают». Какое поведение ожидается?echo -- -e
тоже не работает. Традиционно (по крайней мере, с утилитами GNU) двойная черта указывает на конец опций, а остальные остаются в качестве буквальных аргументов.echo
опять безумие Если бы люди только использовалиprintf
и никогда не оглядывались назад.Ответы:
с новой строкой
без перевода строки
с пробелами вокруг:
используя backspace (спасибо Джозефу Р.):
(он выводит SPC BS - e LF, но при отправке на терминал, который отображается
-e
как BS, перемещает курсор назад на один столбец влево, вызывая-
перезапись SPC)Поведение
bash
«Secho
встроенной команды может зависеть от Баш версии. Это также зависит от окружающей среды (POSIXLY_CORRECT
,SHELLOPTS
иBASHOPTS
переменные), параметры (posix
,xpg_echo
), варианты сборки иargv[0]
(sh
VSbash
). Здесь протестировано сGNU bash 4.2.53(1)
, сборкой по умолчанию, опциями по умолчанию, пустой средой, вызываемой какbash
. Работает также сzsh 5.0.5
.источник
echo -e 'x\b-e'
echo
команды. Отношение не обязательно.echo -e ' \b-e'
выводит space-backspace-dash-e. Только отображенный в терминале, он создаст иллюзию, что это dash-e.echo -e "\0-e"
выводитNUL-dash-e
. Это просто , что терминалы игнорируют , что NUL символы (NULs даже используется для отправки некоторых терминалов (которые не поддерживают управление потоком) , чтобы дать им время , чтобы делать другие длинные вещи , как возврат каретки. Смотрите раздел под Задержкой и отступов вterminfo(5)
.)Лучшее решение - не использовать
echo
, а использоватьprintf
вместо этого.Это работает с произвольными переменными:
... то есть вам не нужно выполнять какую-либо специальную подготовку / модификацию в другом месте вашего кода, основываясь на знании того, что значение будет
echo
d.Кстати, спецификация команды оболочки POSIX
echo
подтверждает, что она непереносима при ее реализации, и содержит примечание на эту тему:(Акцент добавлен).
Тем не менее, в системах GNU существует альтернатива: запрос поведения, соответствующего стандартам.
источник
echo -e
она портативна. Это говорит о том, что-n
следует избегать и избегать последовательностей побега.echo -e
избегает обоих. Но, как вы указали в последней части вашего ответа, в системах GNUecho
не заботится о том, чтобы по умолчанию вообще соответствовать POSIX, а POSIX отмечает только переносимость между системами POSIX.-e
в той части спецификации, с которой я связан. Не могли бы вы предоставить ссылку или цитату, которая покрывает это?-e
не упоминаются, а также-e
переносимы (опять же, для всех систем POSIX). Чтобы быть справедливым, то, что вы цитировали, является информативным, но нормативный текст говорит то же самое: «Если первый операнд -n или любой из операндов содержит символ <backslash>, результаты определяются реализацией».echo
необходимо выдать все аргументы без поведения, определенного стандартом противоположным образом. Таким образом - в отличие от почти всех других инструментов командной строки, охватываемых спецификацией POSIX, -echo
фактически определяет поведение для аргументов, которые не приведены: их печать. Нет места для добавления новых флагов без нарушения спецификации.OPTIONS
раздел, в котором он установлен в черно-белом:Implementations shall not support any options
.С GNU
echo
«S-e
с ASCII - кодами символов:055
является восьмеричным числом ASCII для-
(см.man ascii
краткий справочник).источник
/bin/echo
действительно определено POSIX. Однако его интерпретация восьмеричных escape-последовательностей является расширением XSI к базовой спецификации.-e
это расширение, есть ли способ навязать поведение чистого POSIXecho
? Я думаю, это устранило бы всю неуверенность в этом.POSIXLY_CORRECT=1
приведет к POSIX-совместимому поведению для GNU/bin/echo
.Хотя очевидным, стандартным и рекомендуемым решением является использование
printf
, сделать этоecho
может быть довольно сложно в зависимости от реализации (не так сложно, как-n
кажется).POSIX.2017 совместимый
echo
сPOSIX требует
echo -e
вывода-e<newline>
. Так что это простотам. 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 , по крайней мере) , и большинство BSDsecho
встроенный изdash
,ksh88
, Борна оболочки, CSH, Tcsh, шикарном, RC, ES, akangaecho
(/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
-На оболочки , как BusyBoxsh
илиsh
некоторых BSDs, последние версииksh93
(на некоторых системах, а также с некоторыми значениями$PATH
) с настройками по умолчанию,yash
с$ECHO_STYLE
одним изGNU
илиZSH
:Реализации, которые поддерживают,
-e
всегда поддерживают-n
, поэтому:будет работать так же.
ЗШ
zsh
«Secho
является единственной реализацией , что я знаю , что поддерживает истекший вариант маркеров (-
).Делая это единственной подобной Борну оболочкой,
echo
которая может выводить произвольные данные (также потому, что она единственная, которая поддерживает байты NUL в своих переменных и аргументах своих встроенных функций) с помощьюecho -E - "$data"
)За исключением проблемы NUL-байтов, другими реализациями, которые могут выводить произвольные данные, являются FreeBSD или macOS,
/bin/echo
где вы можете сделать:(в этой реализации
\c
распознается только в конце, и никакая другая escape-последовательность не поддерживается).И
yash
s:(хотя обратите внимание, что
yash
переменные могут содержать только текст, поэтому не произвольные последовательности байтов в локалях, где не все последовательности байтов могут образовывать допустимые символы, как в тех, которые используют UTF-8 в качестве своей карты символов).источник
Используйте,
-n
чтобы избежать новой строки:источник
zsh
где-
находится конец разделителя опций, или во всехecho
реализациях, которые не поддерживают-n
( хотя и те, которые-e
поддерживают-n
)