У вас есть backticks (т.е. `cmd`) в * sh оболочках устарели?

Я неоднократно видел этот комментарий в Unix и Linux, а также на других сайтах, в которых фразы «backticks устарели», в отношении таких оболочек, как Bash & Zsh.

Является ли это утверждение истинным или ложным?

2 Solutions collect form web for “У вас есть backticks (т.е. `cmd`) в * sh оболочках устарели?”

Ссылаясь на спецификацию Open Group на командных командах командной оболочки , в частности в этом разделе «2.6.3 Command Substitution», это утверждение относительно устаревания backtick фактически неверно. Обе формы подстановки команд, backticks ( `..cmd..` ) или доллара parens ( $(..cmd..) ) по-прежнему поддерживаются в той мере, в какой это спецификация.

выдержка

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

  $(command) or (backquoted version): `command` 

Оболочка расширяет подстановку команд, выполняя команду в среде подсетей (см. Shell Execution Environment) и заменяя подстановку команд (текст команды плюс включающий $() или backquotes) на стандартный вывод команды, удаляя последовательности один или несколько символов в конце замены. Встроенные символы перед окончанием вывода не должны удаляться; однако они могут рассматриваться как полевые разделители и исключаться при разделении поля в зависимости от значения IFS и цитирования, которое действует. Если вывод содержит нулевые байты, поведение не задано.

В стиле обратной подстановки команды <backslash> сохраняет свое буквальное значение, за исключением случаев, когда следуют: '$', ' \` ' или <backslash> . Поиск совпадающей обратной кавычки должен выполняться с помощью первого некотируемого неэкзацированного обратного кавычки; во время этого поиска, если в комментариях оболочки встречается неэкранированный backquote, здесь-документ, встроенная подстановка команды формы $(command) или строка с кавычками, не определены результаты. Строка с одним кавычками или двойным кавычком, которая начинается, но не заканчивается, в последовательности « `...` » вызывает неопределенные результаты.

С формой $(command) все символы, следующие за открытой скобкой, соответствуют соответствующей закрывающей скобке. Любой допустимый сценарий оболочки можно использовать для команды, за исключением сценария, состоящего исключительно из повторных указаний, которые производят неуказанные результаты.

Итак, почему все говорят, что backticks устарели?

Потому что большинство случаев использования должно использовать форму доллара-parens против обратных ссылок. Многие из наиболее авторитетных сайтов (в том числе U & L) часто говорят об этом также, так что это здравый совет, но это просто хороший совет.

  • BashFAQ # 082 – Почему $ (…) предпочитается над `…` (backticks)?

выдержка

`...` – устаревший синтаксис, требуемый только самой старой из не-POSIX-совместимых оболочек bourne. Существует несколько причин всегда предпочитать синтаксис $(...)

  • Bash Hackers Wiki – устаревший и устаревший синтаксис

выдержка

Это более старая совместимая с Bourne форма подстановки команд . Оба синтаксиса `COMMANDS` и $(COMMANDS) задаются POSIX, но последний очень предпочтителен, хотя первый, к сожалению, все еще очень распространен в сценариях. Новые подстановки команд широко применяются каждой современной оболочкой (а затем и некоторыми). Единственная причина использования backticks – совместимость с реальной оболочкой Bourne (например, Heirloom). Замена команд Backtick требует специального экранирования при вложенности, а примеры, найденные в дикой природе, ненадлежащим образом цитируются чаще. См .: Почему $ (…) предпочитается над `…` (backticks)? ,

  • Стандартное обоснование POSIX

выдержка

Из-за этих непоследовательных поведений альтернативное подмену подзапросов не рекомендуется для новых приложений, которые вставляют подстановки команд или пытаются встраивать сложные скрипты.

ПРИМЕЧАНИЕ. Эта третья выдержка (выше), вероятно, является источником того, почему многие считают обратные ссылки устаревшими. Он показывает несколько ситуаций, когда обратные элементы просто не работают, но метод более поздних долларовых парендов:

Кроме того, синтаксис backquoted имеет исторические ограничения на содержимое встроенной команды. В то время как новая форма «$ ()» может обрабатывать любые допустимые встроенные скрипты, обратная форма не может обрабатывать некоторые допустимые скрипты, которые включают backquotes.

Если вы продолжите чтение этого раздела, сбои будут подсвечены, показывая, как они будут работать с обратными вызовами, но работают с использованием новелла с новером.

Выводы

Таким образом, обычно предпочтительнее использовать долларовые пары против обратных сигналов, но вы фактически не используете то, что технически не рекомендуется. После прочтения всего этого вы должны убрать, что вам настоятельно рекомендуется использовать долларовые пары, если у вас нет насущной необходимости использовать обратные ссылки.

Это не устарело, но обратные элементы ( `...` ) – это устаревший синтаксис, требуемый только самой старой из не-POSIX-совместимых оболочек bourne, а $(...) является POSIX и более предпочтительным по нескольким причинам:

  • Обратные косые черты ( \ ) внутри backticks обрабатываются неочевидным образом:

     $ echo "`echo \\a`" "$(echo \\a)" a \a $ echo "`echo \\\\a`" "$(echo \\\\a)" \a \\a # Note that this is true for *single quotes* too! $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" foo is \, bar is \\ 
  • Вложенная цитата внутри $() намного удобнее:

     echo "x is $(sed ... <<<"$y")" 

    вместо:

     echo "x is `sed ... <<<\"$y\"`" 

    или написать что-то вроде:

     IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts` 

    потому что $() использует совершенно новый контекст для цитирования

    который не переносится, поскольку ракеты Bourne и Korn потребуют этих обратных косых черт, в то время как Bash и тире нет.

  • Синтаксис для замены команд вложенности проще:

     x=$(grep "$(dirname "$path")" file) 

    чем:

     x=`grep "\`dirname \"$path\"\`" file` 

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

    Еще несколько примеров:

     echo `echo `ls`` # INCORRECT echo `echo \`ls\`` # CORRECT echo $(echo $(ls)) # CORRECT 
  • Он решает проблему непоследовательного поведения при использовании backquotes:

    • echo '\$x' выходы \$x
    • echo `echo '\$x'` выводит $x
    • echo $(echo '\$x') выдает \$x
  • Синтаксис Backticks имеет исторические ограничения на содержимое встроенной команды и не может обрабатывать некоторые допустимые скрипты, которые включают backquotes, в то время как новая форма $() может обрабатывать любой допустимый встроенный скрипт.

    Например, в противном случае действительные встроенные скрипты не работают в левом столбце, но работают с правильным IEEE :

     echo ` echo $( cat <<\eof cat <<\eof a here-doc with ` a here-doc with ) eof eof ` ) echo ` echo $( echo abc # a comment with ` echo abc # a comment with ) ` ) echo ` echo $( echo '`' echo ')' ` ) 

Поэтому синтаксис для подстановки $ -prefixed- команд должен быть предпочтительным, потому что он визуально чист с чистым синтаксисом (улучшает человеческую и машинную читаемость), он является гнездовым и интуитивно понятным, его внутренний разбор является отдельным, и он также более последователен ( со всеми другими расширениями, которые анализируются из двойных кавычек), где обратные ссылки являются единственным исключением, и ` персонаж легко маскируется при прикосновении " что делает его еще более трудным для чтения, особенно с небольшими или необычными шрифтами.

Источник: Почему $(...) предпочитается над `...` (backticks)? в BashFAQ

Смотрите также:

  • Стандартная секция POSIX «2.6.3 Command Substitution»
  • Обоснование POSIX для включения синтаксиса $ ()
  • Замена команды
  • bash-hackers: замена команд
  • zsh glob pattern для соответствия всем файлам, кроме одного, не работает, несмотря на то, что EXTENDED_GLOB установлен
  • Таинственное повторение введенной команды в оболочке
  • Zsh: расширение хэшированных имен каталогов в приглашении
  • Создание псевдонима, отображающего аргументы в середине команды
  • Переименование файлов в лексикографическом порядке с помощью числового шаблона, который последовательно увеличивается с фиксированным заполнением
  • Тысяча разделителей в printf в zsh
  • Экспортировать несколько опций в $ GREP_OPTIONS
  • / etc / paths в OS X и других Unices
  • Как включить вывод скрипта в приглашение zsh
  • Вставка имеет нечетное поведение в оболочке
  • запуск экрана в оболочке не может найти сеансы, но запуск экрана во время входа в ssh может
  • Linux и Unix - лучшая ОС в мире.