Làm thế nào để lồng các que ngược Bash đúng cách


91

Hoặc tôi đã bỏ lỡ một số phản ứng dữ dội hoặc phản ứng dữ dội dường như không hoạt động với quá nhiều lập trình-trích dẫn-vòng lặp.

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

hello1-hello2-hello3-echo hello4

Muốn

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

Câu hỏi có lẽ nên đọc "Cách sử dụng Bash backticks một cách đệ quy". Điều đó sẽ giúp ích cho nhân viên Google.
Joey Adams

bạn đang cố gắng làm gì vậy? điều này không có ý nghĩa gì cả.
ghostdog 74

1
@joey, tiêu đề đã thay đổi, chào mừng bạn: D
Stormenet

1
Rất tiếc, cào cái đó. Nó nên đọc "Làm cách nào để lồng các dấu gạch ngược vào bash?" . Tôi đã trộn lẫn đệ quy và lồng vào nhau.
Joey Adams

deprecatedVì vậy, được sử dụng $(cmd).
Timo

Câu trả lời:


144

Sử dụng $(commands)thay thế:

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

$(commands) hoạt động tương tự như backticks, nhưng bạn có thể lồng chúng.

Bạn cũng có thể quan tâm đến việc mở rộng phạm vi Bash:

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10

+1 như {1..10}. Giới hạn nó bằng mảng? ZSH có thể "$ {$ (date) [2,4]}". Tại sao không: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
hhh

35

nếu bạn khăng khăng sử dụng backticks, có thể thực hiện theo

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

bạn phải đặt dấu gạch chéo ngược, \\ \\\\ \\\\\\\\gấp 2 lần, v.v., nó rất xấu, hãy sử dụng $(commands)như đề xuất khác.


11

Bất kỳ lúc nào bạn muốn đánh giá một lệnh sử dụng command substitution:

$(command)

Bất kỳ lúc nào bạn muốn đánh giá một biểu thức số học, hãy sử dụng expression substitution:

$((expr))

Bạn có thể lồng những cái này như thế này:

Giả sử file1.txt dài 30 dòng và file2.txt dài 10 dòng, bạn có thể đánh giá một biểu thức như sau:

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

sẽ xuất ra 20 (sự khác biệt về số dòng giữa hai tệp).


10

Sẽ dễ dàng hơn rất nhiều nếu bạn sử dụng $(cmd) cú pháp thay thế lệnh của bash, cú pháp được lồng vào nhau thân thiện hơn nhiều:

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

5
Điều này không bị hạn chế đối với bash . Nó có sẵn trong tất cả các shell tuân theo POSIX 1003.1 (“POSIX shell”) và hầu hết các shell có nguồn gốc từ Bourne ( ksh , ash , dash , bash , zsh , v.v.) mặc dù không phải là shell Bourne thực tế (tức là heirloom.sourceforge.net /sh.html ).
Chris Johnsen

wow, dấu thời gian trên câu trả lời này là SẮC với dấu thời gian trên câu trả lời @joey_adams! Đồng bộ theo nghĩa đen của nó :) Cũng ủng hộ ở đây (:
drevicko

0

Đôi khi việc lồng backtick có thể được thay thế bằng xargsvà các đường ống

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

Hạn chế của giải pháp này là:

  • Tất cả các đối số phải được cung cấp theo thứ tự ngược lại (4 → 1);
  • Tất cả các đối số trở thành khoảng trắng được phân tách (có thể giải quyết với tr):

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


Hãy hiển thị một trường hợp sử dụng thực tế.

Các lệnh sau hoạt động trong bash, nhưng không hoạt động trong tcsh (lồng vào backtick không được xử lý tốt trong tcsh)

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

Chúng có thể được thay thế bằng

$ which bash | xargs dirname | xargs ls
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.