Чем отличается $(cmd) от `cmd`

Bash

Держу пари многие, используют оба варианта даже не задумываясь. Порой в скриптах я могу одновременно встретить как первую, так и вторую конструкцию. И аргумент всегда один — но оно же работает, чо душнишь?

А спорим ты не знаешь чем отличается:

var=$(command)


от

var=`command`

 

А в чём, тогда подвох?

Да всё просто — gravemarks (надгробия) морально устарели и в бест-практиках нынче $(command).

Ну и конечно же при использовании надгробий будет много геморроя например с вложенными командами и экранированием. Вот пример:

list=$(ls -l $(cat bashdays.txt))


либо

list=`ls -l \`cat bashdays.txt\``

Кстати если в Bash скрипте видишь, что используются обе конструкции, высока вероятность, что скрипт писался копипастой из разных источников.

Если на чистоту, то эти два примера ничем не отличаются, логика работы будет одинакова. Выполнится какая-либо команда (command) и ее результат запишется в переменную var.

Эти штуки, кривые кавычки, называются backticks = обратные палки/знаки или gravemarks = надгробия.

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

Ну и порой использование gravemarks влияет на результаты:

A="A_VAR"
echo $(echo "\$A")
echo `echo "\$A"`


Вроде две одинаковые команды, а выведут разный результат:

$A
A_VAR


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

echo `echo "\\$A"`


В результате получим вывод на экран: $A как и в первом варианте с $().

Вот такие пироги. Так что если до сих пор используешь gravemarks, посмотри в сторону $(), оно как бы правильнее. Но опять же, со своим уставом куда-то там не ходят. Выбор каждого.

Ладно. Давай краба, увидимся!