Як правильно вкладати зворотні Bash


91

Або я пропустив деякий люфт, або люфт, здається, не працює із занадто великою кількістю програмістів-цитат.

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

hello1-hello2-hello3-echo hello4

Розшукується

hello1-hello2-hello3-hello4-hello5-hello6-...

Питання, ймовірно, має читатись "Як використовувати рекурсивні зворотні лінії Bash". Це має допомогти працівникам Google.
Джої Адамс,

що ти намагаєшся зробити.? це зовсім не має значення.
ghostdog74

1
@joey, заголовок змінено, ласкаво просимо: D
Stormenet

1
На жаль, подряпайте це. У ньому має бути написано "Як вкласти зворотні позначки в bash?" . У мене переплуталися рекурсія та гніздування.
Джої Адамс,

Зворотні лапки є deprecated, тому використання $(cmd).
Тимо

Відповіді:


144

$(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 може "$ {$ (дата) [2,4]}". Чому б і ні: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
hhh

35

якщо ви наполягаєте на використанні зворотних міток, можна виконати наступні дії

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

вам доведеться ставити зворотні скісні риски, \\ \\\\ \\\\\\\\вдвічі і так далі, це просто дуже потворно, використовуйте, $(commands)як пропонували інші.


11

Кожного разу, коли ви хочете оцінити використання команди command substitution:

$(command)

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

$((expr))

Ви можете вкласти їх наступним чином:

Скажімо, file1.txt має 30 рядків, а file2.txt - 10 рядків, ніж ви можете оцінити такий вираз:

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

який виводив би 20 (різниця в кількості рядків між двома файлами).


10

Набагато простіше, якщо ви використовуєте $(cmd) синтаксис заміни команд bash , який набагато зручніше вкладати:

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

5
Це не обмежується bash . Він доступний у всіх оболонках, які відповідають POSIX 1003.1 (“оболонки POSIX”) та більшості оболонок, отриманих від Борна ( ksh , ash , dash , bash , zsh тощо), хоча не в дійсній оболонці Борна (тобто 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 (вкладання backtick не дуже добре обробляється в tcsh)

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

Їх можна замінити на

$ which bash | xargs dirname | xargs ls
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.