Что `(backquote / backtick) означает в командах?

160

Я наткнулся на следующую команду:

sudo chown `id -u` /somedir

и мне интересно: что означает `символ. Например, я заметил, что хотя приведенная выше команда работает хорошо, приведенная ниже не работает:

sudo chown 'id -u' /somedir
GWS
источник

Ответы:

201

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

И что

sudo chown `id -u` /somedir

Эффективно работает (в зависимости от вашего идентификатора пользователя ) это:

sudo chown 1000 /somedir
  \    \     \     \
   \    \     \     `-- the second argument to "chown" (target directory)
    \    \     `-- your user ID, which is the output of "id -u" command
     \    `-- "chown" command (change ownership of file/directory)
      `-- the "run as root" command; everything after this is run with root privileges

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

Кстати, если вы когда-либо хотели использовать обратную косую черту буквально, например, в строке, вы можете избежать ее, поместив \перед ней обратную косую черту ( ).

rozcietrzewiacz
источник
36
Это довольно хорошо объясняет обратные пометки, но использование $(your expression)- лучший способ сделать то же самое, что $()позволяет вам вкладывать выражения. например: cd $(dirname $(type -P touch))войдет в каталог, содержащий touchкоманду
Хаджа Минхаджуддин
11
@KhajaMinhajuddin Вы определенно правы насчет вложения - вышеупомянутый вопрос описывает это подробно. Но даже несмотря на то, что я считаю, что это хорошая практика для использования $()в большинстве ситуаций, это не делает обратные удары хуже . Для практических целей нужно признать, что они гораздо быстрее набираются в командной строке (2 нажатия клавиш по сравнению с минимум 5 включительно Shift).
rozcietrzewiacz
2
@rozcietrzewiacz Ваше последнее замечание, вероятно, верно для большинства клавиатур, но $( )определенно легче набрать, чем, ` `по крайней мере, на французской клавиатуре.
Jlliagre
1
@KhajaMinhajuddin Вы можете вкладывать обратные метки, но вам нужно избегать 2-го уровня, и для 2-го уровня вам нужно 3 обратных, 3-й уровень - 5 обратных, 4-й уровень 7 и т. Д.
JustinCB
66

Я хотел бы добавить еще несколько пунктов здесь.

Обратный удар `…`фактически называется подстановкой команд . Целью подстановки команд является оценка команды, которая находится внутри обратной черты, и предоставление ее результата в качестве аргумента для фактической команды.

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

И так

sudo chown $(id -u) /somedir

может быть предпочтительнее других.

И еще одна вещь, которую вы должны здесь отметить, это отношение подстановки команд с правилами цитирования bash, как упомянуто в документе bash .

Если подстановка встречается в двойных кавычках, разделение слов и расширение имени файла в результатах не выполняются.

Каннан Мохан
источник
8
Кроме того, $(...)гнезда лучше.
Кусалананда
$()и "``"не работают одинаково
Кун
10

Одна пояснительная записка редко освещается:

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

Итак, чтобы продолжить предыдущий пример:

file `which hostname`

будет работать как положено, но в:

file `which hostnameX`

whichвернет ошибку, и этот вывод перейдет к стандартной ошибке, а не подставляется в командную строку рядом с file; стандартного вывода вообще не будет, что можно подтвердить, выполнив:

which hostnameX

which hostnameX 2>/dev/null

В этом случае,

file `which hostnameX` 

выдаст два сообщения об ошибке (первое из-за самого себя, which hostnameXа второе сразу после первого из-за самого файла, которое обнаружит, что имя файла отсутствует, и, таким образом, вся команда

существенно снизится до просто:

file

что, конечно, является неправильным использованием и возвратит ошибку использования.

(если вы хотите проверить это самостоятельно, вы можете попробовать:

file `which hostnameX 2>/dev/null`    # just the file-command bad-usage error msg is printed

file `which hostnameX 2>/dev/null` 2>/dev/null  # now nothing is printed on the screen :)
Дейв К
источник
4

Backtick `запускает содержимое вложенной строки, так что-то вроде этого

file `which hostname`

найдет путь к команде hostname и расскажет, как она была построена.

Команда, которую вы задали в своем вопросе, выполняется id -uдля получения эффективного идентификатора пользователя, а затем меняет владельца / somedir на этого пользователя.

юлианский
источник
2

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

например:

$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three

Вышеуказанное приводит к тому, что threeкаталог копируется в мой /homeкаталог.

Ханан Н.
источник
1

Бэкстики напоминают подстановку команд. Этот синтаксис обратных кавычек архаичен, и знать знак доллара с два скобкой является общей: $().

Что такое подстановка команд?

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

Пример с датой:

thedate=$(date)

Затем мы можем напечатать результат: 'Дата:% s \ n' "$ thedate" `.

  1. Синтаксис команды замены $().
  2. Сама команда есть date.
  3. Объединяя оба, мы получаем, $(date)что его выход является заменой.
  4. Мы отображаем выходное значение, удерживаемое переменной с printfпомощью команды выше.
user9303970
источник