В чем преимущество использования $() вместо обратных кавычек в скриптах оболочки?
есть два способа захватить вывод командной строки в bash:
Legacy Bourne shell backticks
``:
var=`command`
$()синтаксис (который, насколько я знаю, является специфичным для Bash)
var=$(command)
есть ли какая-либо польза от использования второго синтаксиса по сравнению с backticks? Или два полностью 100% аналог?
8 ответов:
главным из них является способность гнездо они, команды внутри команд, не теряя рассудка, пытаясь выяснить, будет ли какая-то форма побега работать на задних палочках.
пример, хотя и несколько надуманный:
deps=$(find /dir -name $(ls -1tr 201112[0-9][0-9]*.txt | tail -1l) -print), который даст вам список всех файлов в папке
/dirдерево каталогов, которые имеют то же имя, что и самый ранний датированный текстовый файл с декабря 2011 года (a).другой пример что-то вроде получения имени (не полного пути) родительского каталога:
pax> cd /home/pax/xyzzy/plugh pax> parent=$(basename $(dirname $PWD)) pax> echo $parent xyzzy
(a) теперь конкретные команда может фактически не работать, я не проверял функциональность. Итак, если вы проголосуете за меня, вы потеряли из виду намерение :-) это означает только иллюстрацию того, как вы можете гнездиться, а не как готовый к производству фрагмент без ошибок.
Предположим, вы хотите найти каталог lib, соответствующий where это. У вас есть выбор:
libdir=$(dirname $(dirname $(which gcc)))/lib libdir=`dirname \`dirname \\`which gcc\\`\``/libпервый проще, чем второй - используйте первый.
от man bash:
$(command) or `command` Bash performs the expansion by executing command and replacing the com- mand substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file). When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, `, or \. The first backquote not preceded by a backslash terminates the command sub- stitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.
обратные апострофы (
`...`) - это устаревший синтаксис, необходимый только самым старым из несовместимых с POSIX Bourne-оболочек и$(...)является 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 }' /etc/hosts`, потому что
$()использует совершенно новый контекст для цитированиякоторый не является портативным, поскольку Bourne и Korn shells потребовали бы этих обратных косых черт, в то время как Bash и dash этого не делают.
синтаксис для подстановок команд вложенности проще:
x=$(grep "$(dirname "$path")" file)чем:
x=`grep "\`dirname \"$path\"\`" file`, потому что
$()обеспечивает совершенно новый контекст для цитирования, поэтому каждая подстановка команд защищена и может лечиться самостоятельно без особого беспокойства по поводу цитирования и побега. При использовании backticks он становится все уродливее и уродливее после двух и выше уровней.несколько примеров:
echo `echo `ls`` # INCORRECT echo `echo \`ls\`` # CORRECT echo $(echo $(ls)) # CORRECTон решает проблему непоследовательного поведения при использовании обратных кавычек:
echo '$x'выходы$xecho `echo '$x'`выходы$xecho $(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 ')' ` )$-с префиксом команду должен быть предпочтительным методом, потому что он визуально ясен с чистым синтаксисом (улучшает читаемость человека и машины), он удобен и интуитивно понятен, его внутренний разбор является отдельным, а также более последовательным (со всеми другими расширениями, которые анализируются изнутри двойных кавычек) , где обратные кавычки являются единственными исключение и`характер легко маскируется, когда рядом с"что делает его еще более трудным для чтения, особенно с маленькими или необычным шрифтом.источник: почему
$(...)предпочтительнее`...`(backticks)? в BashFAQЧитайте также:
В дополнение к другим ответы,
$(...)выделяется визуально лучше, чем
`...`обратные кавычки выглядеть слишком много, как апострофы; это варьируется в зависимости от шрифта, который вы используете.
(и, как я только что заметил, backticks намного сложнее вводить во встроенные примеры кода.)
это стандарт POSIX, который определяет
$(command)форма подстановки команды. Большинство оболочек, используемых сегодня, совместимы с POSIX и поддерживают эту предпочтительную форму по сравнению с архаичной нотацией обратного отсчета. Элемент команду раздел (2.6.3) документа языка оболочки описывает это:подстановка команд позволяет заменять вывод команды вместо самого имени команды. Замена команд должна происходить, когда команда прилагается следующим образом:
$(command)или (закавыченная версия):
`command`оболочка должна расширить подстановку команд, выполнив команда в подсеточной среде (см. Среда Выполнения Оболочки) и замена команды substitution (текст команда плюс заключая "$ () " или обратные кавычки) со стандартным выводом команда, удаление последовательностей из одного или нескольких
<newline>символы на конец подмены. Встроенный<newline>символы до конца вывод не должен быть удален; однако, они могут рассматриваться как разделители полей и устраняются при разделении полей, в зависимости от значение IFS и цитирование, которое действует. Если вывод содержит любые нулевые байты, поведение не определено.в стиле обратной кавычки подстановки команд,
<backslash>будет сохранить буквальное значение, за исключением случаев, когда за ним следует:'$','`', или<backslash>. Поиск соответствующей обратной цитаты должен быть удовлетворен по первой некотируемой не экранированной обратной кавычке; во время этого поиска, Если a не экранированная обратная цитата встречается в комментарии оболочки, a здесь-документ, встроенная команда подстановки $(команда) форма или строка в кавычках, неопределенные результаты происходят. Одинарные кавычки или строка в двойных кавычках, которая начинается, но не заканчивается в пределах "`...`" последовательность дает неопределенные результаты.долларов(команда) формы, все символы после открытия скобка с скобка составляют команда. Любой допустимый сценарий оболочки может быть использован для команда, за исключением скрипт, состоящий исключительно из переадресаций, который производит неуказанные результаты.
результаты замены команд не обрабатываются для дальнейшей обработки расширение Тильды, расширение параметров, подстановка команд или арифметическое разложение. Если внутри происходит подстановка команд двойные кавычки, разделение полей и расширение пути не должны быть выполняется по результатам замены.
подстановка команд может быть вложенной. Чтобы указать вложенность в пределах версия с обратными кавычками, приложение должно предшествовать внутренним обратным кавычкам с
<backslash>символы; например:
\`command\`синтаксис командного языка оболочки имеет неоднозначность для расширений, начинающихся с "
$((", который может ввести арифметическое расширение или подстановку команд, которая начинается с подобласти. Арифметическое разложение имеет приоритет; то есть оболочка должна сначала определить может ли он анализировать расширение как арифметическое расширение и будет только разбирать расширение как подстановку команд если он определяет, что он не может разобрать расширение как арифметику расширение. Оболочка не должна оценивать вложенные расширения при выполнении этого определения. Если он встречает конец ввода, не определив уже что он не может разобрать расширение как арифметическое расширение, оболочка должна рассматривать расширение как неполное арифметическое расширение и сообщать о синтаксической ошибке. Соответствующая заявка должна обеспечивать, чтобы она отделяла "$(" и '(в двух жетонов (то есть, разделите их пробелом) в команду подстановка, которая начинается с подоболочки. Например, подстановка команды, содержащая одну подобласть, может быть записана как:
$( (command) )
это вопрос наследия, но я придумал совершенно правильный пример
$(...)over`...`.я использовал удаленный рабочий стол для windows под управлением cygwin и хотел перебрать результат команды. К сожалению, символ backtick невозможно было ввести, либо из-за удаленного рабочего стола, либо из-за самого cygwin.
разумно предположить, что знак доллара и круглые скобки будет легче вводить в таких странных настройках.
Comments