Как правильно вложить обратные кавычки в Bash

95

Либо я пропустил некоторую обратную реакцию, либо обратная реакция, похоже, не работает со слишком большим циклом программиста-цитаты.

$ echo "hello1-`echo hello2-\`echo hello3-\`echo hello4\`\``"

hello1-hello2-hello3-echo hello4

Хотел

hello1-hello2-hello3-hello4-hello5-hello6-...
ххх
источник
Вопрос, вероятно, следует читать «Как рекурсивно использовать обратные кавычки Bash». Это должно помочь гуглерам.
Джои Адамс
что вы пытаетесь сделать? это вообще не имеет значения.
ghostdog74
1
@joey, название изменено, добро пожаловать: D
Stormenet
1
Ой, поцарапайте это. Он должен читать «Как вложить обратные кавычки в bash?» . Я перепутал рекурсию и вложение.
Джои Адамс
Обратные кавычки есть deprecated, поэтому используйте $(cmd).
Timo

Ответы:

149

$(commands)Вместо этого используйте :

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

$(commands) делает то же самое, что и обратные кавычки, но их можно вкладывать.

Вас также могут заинтересовать расширения диапазона Bash:

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10
Джои Адамс
источник
+1 как {1..10}. Ограничить его массивом? ZSH может "$ {$ (date) [2,4]}". Почему бы и нет: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
чч
35

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

$ echo "hello1-`echo hello2-\`echo hello3-\\\`echo hello4\\\`\``"

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

ВЫ
источник
11

Каждый раз, когда вы хотите оценить команду, используйте command substitution:

$(command)

Каждый раз, когда вы хотите оценить арифметическое выражение, используйте expression substitution:

$((expr))

Вы можете вложить их так:

Скажем, file1.txt имеет длину 30 строк, а file2.txt - 10 строк, тогда вы можете вычислить такое выражение:

$(( $(wc -l file1.txt) - $(wc -l file2.txt) ))

что выведет 20 (разница в количестве строк между двумя файлами).

toobsco42
источник
10

Это будет намного проще, если вы используете $(cmd) синтаксис подстановки команд bash , который гораздо удобнее вложить:

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4
Марк Рушаков
источник
5
Это не ограничивается bash . Он доступен во всех оболочках, которые соответствуют POSIX 1003.1 («оболочки POSIX») и в большинстве оболочек, производных от Bourne ( ksh , ash , dash , bash , zsh и т. Д.), Но не в самой оболочке Bourne (т.е. heirloom.sourceforge.net /sh.html ).
Крис Джонсен
вау, отметка времени в этом ответе ИДЕНТИЧНА тому, что была в ответе @joey_adams! Синхронность в самом буквальном смысле :) Голосование и здесь тоже (:
drevicko
0

Иногда вложение обратных кавычек можно заменить на xargsи трубы

$ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1
hello1 hello2 hello3 hello4

Недостатками этого решения являются:

  • Все аргументы должны быть указаны в обратном порядке (4 → 1);
  • Все аргументы разделяются пробелами (разрешается с помощью tr):

    $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1 | tr ' ' '-'
    hello1-hello2-hello3-hello4
    


Покажем реальный вариант использования.

Следующие команды работают в bash, но не в tcsh (вложение обратных кавычек не очень хорошо обрабатывается в tcsh)

$ ls $(dirname $(which bash))
$ ls `dirname \`which bash\``

Их можно заменить на

$ which bash | xargs dirname | xargs ls
GC
источник