Были ли помечены обратные пометки (то есть `cmd`) в оболочках * sh?

118

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

Это утверждение верно или ложно?

SLM
источник
См. Почему обратные кавычки в сценарии оболочки помогают мне cdнайти каталог, в котором объясняется, почему $(...)нотация проще в использовании, чем вложенные обратные кавычки.
Джонатан Леффлер
2
Изюминка здесь
Тревор Бойд Смит
1
По крайней мере, один Unix, AIX, задокументировал, что обратные пометки устарели . «Несмотря на то, что синтаксис обратной цитаты принят ksh, он считается устаревшим в стандарте X / Open Руководство по переносимости, выпуск 4 и стандартах POSIX. Эти стандарты рекомендуют, чтобы переносимые приложения использовали синтаксис $ (command)». ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.osdevice/…
Кристофер
У меня есть определенная разница в «GNU bash, версия 3.2.57 (1) -релиз (x86_64-apple-darwin14)» на Mac 10.10: matchingLines=$( grep -n '\$-PARAMETER' ... | ... )работает, matchingLines= backtick the same stuff backtickне работает - похоже, теряет обратную косую черту в обратной косой черте. (Это не мой сценарий ...)
Денис

Ответы:

126

Есть два разных значения слова «не рекомендуется».

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

Новый Оксфордский Американский Словарь

По этому определению обратные ссылки не рекомендуются.

Устаревшее состояние также может указывать на то, что функция будет удалена в будущем.

- Википедия

По этому определению обратные пометки не являются устаревшими.

Все еще поддерживается:

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

выдержка

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

          $(command)

          or (backquoted version):

          `command`

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

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

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

Так почему же все говорят, что обратные ходы устарели?

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

  • BashFAQ # 082 - Почему $ (...) предпочтительнее, чем `...` (обратные пометки)?

    выдержка

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

    ...

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

    выдержка

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

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

    выдержка

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

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

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

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

Выводы

Поэтому предпочтительно, чтобы вы использовали долларовые паренсы вместо кавычек, но на самом деле вы не используете что-то, что технически «устарело», как в «это перестанет работать полностью в некоторой запланированной точке».

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

SLM
источник
26
По большей части значений осуждается , я (и вы) хотел бы сказать , что обратные кавычки являются устаревшими. Это в основном вопрос терминологии.
Стефан Шазелас
4
@StephaneChazelas - Согласен! Я буду продолжать говорить ppl, что они устарели, но обратные пометки не были официально «устарели» в том смысле, что они будут активно удалены из базы кода любой оболочки в ближайшем будущем. По крайней мере, ничего, что я знаю.
SLM
3
Моя интерпретация заключается в том, что обратные кавычки поддерживаются исключительно потому, что они слишком укоренились в существующем коде, чтобы формально устареть. Я никогда не слышал аргументов за то, чтобы продолжать использовать их в новом коде.
chepner
3
@ Да, я думаю, ты понял - я отстранился и не заметил. Нет почти никакой причины использовать эти вещи, за исключением того, что это может быть немного чище, когда наслоение подоболочек так $( cmd `cmd`)немного $( cmd $(cmd))проще, чем - его легче читать. Я просто всегда считал устаревшую функцию в программном обеспечении официально помеченной для удаления вышестоящей версией - и я никогда не слышал ничего подобного. Мне все равно - не любить могилу.
mikeserv
3
Возможно, вы захотите добавить следующую цитату из стандартного обоснования POSIX : Из-за этих противоречивых поведений разнообразие подстановок команд в кавычках не рекомендуется для новых приложений, которые вкладывают подстановки команд или пытаются встроить сложные сценарии. Хотя это не формальное осуждение, так как раздел обоснования является информативным и ненормативным, в нем предлагается избегать дальнейшего использования обратных галочек.
jw013
15

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

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

    $ 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`

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

    который не является переносимым, так как оболочкам Борна и Корна потребуются эти обратные слеши, в то время как Bash и dash этого не делают.

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

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

    чем:

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

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

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

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

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

    Например, эти действительные встроенные сценарии не работают в левом столбце, но работают в правом 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)? на BASFAQ

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

kenorb
источник