Đối với các vòng lặp trong zsh và bash


57

Tôi đã nhận thấy có hai cách khác nhau để xây dựng các vòng lặp trong zsh :

  1. for x (1 2 3); do echo $x; done
  2. for x in 1 2 3; do echo $x; done

Cả hai đều in:

1
2
3

Câu hỏi của tôi là, tại sao hai cú pháp? Là $xlặp đi lặp lại thông qua một loại đối tượng khác nhau trong mỗi đối tượng ?

Liệu bash có phân biệt tương tự?

Phụ lục:

Tại sao các công việc sau đây?:

#!/bin/zsh
a=1
b=2
c=5    

d=(a b c)    
for x in $d; do print $x;done

Nhưng cái này thì không?:

#!/bin/zsh
a=1
b=2
c=5

d=(a b c)    
# It complains with "parse error near `$d'"
for x $d; do print $x;done 

5
ví dụ: "không hoạt động", đó là kiểu csh cho vòng lặp, bạn đang thiếu dấu ngoặc đơn. for x ($d); do print $x; donesẽ hoạt động và nó sẽ khớp với cú pháp đầu tiên mà bạn đã liệt kê khi bắt đầu câu hỏi của bạn.
Tim Kennedy

1
Thật là điên rồ - rằng hai tuyên bố đó - thực sự không phải cả hai "hoạt động như nhau". Tôi thực sự không thể có được đầu của tôi xung quanh nó! Tôi cần hút một số thứ mà những nhà thiết kế vỏ đó đã hút ', hồi trước, lol.
alex xám

Cẩn thận, có nhiều điều cho câu chuyện này hơn ban đầu xuất hiện. Tôi mời bạn kiểm tra câu trả lời của tôi.
jasonleonhard

Tôi không thấy ai khác đề cập đến nó, nhưng cả hai hình thức đều cho phép bỏ qua do / doing: for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"= {0,2,4}x{a,b,c}. Dấu chấm phẩy áp dụng cho vòng lặp ngoài cùng và chuyển hướng áp dụng cho trong cùng, và nếu bạn cần thay đổi điều đó, bạn chỉ cần niềng răng: for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n= {1,...,9}*({0,2,4}x{a,b,c}). Tất nhiên bạn có thể kết hợp các vòng lặp với mở rộng zsh:for i ("("{0..4..2}","{a..c}")") echo $i
John P

Câu trả lời:


58

Một số dạng lệnh phức tạp như vòng lặp có dạng thay thế trong zsh. Các hình thức này chủ yếu được lấy cảm hứng từ vỏ C , khá phổ biến khi zsh còn trẻ nhưng hiện đã biến mất. Các hình thức thay thế này hoạt động chính xác như các hình thức thông thường, chúng chỉ là một cú pháp khác nhau. Chúng hơi ngắn, nhưng ít rõ ràng hơn.

Hình thức tiêu chuẩn cho forlệnh là for x in 1 2 3; do echo $x; donevà hình thức tiêu chuẩn cho whilelệnh là while test …; do somecommand; done. Ksh, bash và zsh có một dạng thay thế for: for ((i = 0; i < 42; i++)); do somecommand; done, bắt chước các forvòng lặp của các ngôn ngữ như Pascal hoặc C, để liệt kê các số nguyên. Các hình thức kỳ lạ khác tồn tại trong zsh là đặc trưng cho zsh (nhưng thường được lấy cảm hứng từ csh).


Cảm ơn rất nhiều @Guilles. Tôi vẫn còn một chút bối rối. Hình thức nào là cụ thể zsh? Ngoài ra, tôi đã thêm một ví dụ vào cuối OP của mình, nơi tôi không thể tìm ra cách dịch giữa các cú pháp. Nếu sự khác biệt chỉ là cú pháp, tôi nên sửa tập lệnh thứ hai trong phần phụ lục để làm cho nó hoạt động như thế nào?
Amelio Vazquez-Reina

3
@intrpc Xem câu trả lời cập nhật của tôi. Đối với ví dụ cuối cùng của bạn, nó không hoạt động vì bạn đã viết for x $dvà zsh mong đợi inhoặc (nơi bạn đã viết $d. Dấu chấm câu và các từ dành riêng không thể đến từ một mở rộng biến, chúng phải được phân tích cú pháp trước khi shell có thể bắt đầu mở rộng biến.
Gilles 'SO- ngừng trở nên xấu xa'

@intrpc cả hai đều cụ thể zsh. zsh được thiết kế đặc biệt để hỗ trợ cả cú pháp bourne, korn và c-shell, vì nó là sự kết hợp của cả ba.
Tim Kennedy

1
@pseyfert Nó hoạt động, nhưng nó không có bất kỳ lợi thế nào so với các biểu mẫu tôi hiển thị: nó ít di động hơn for (( … ))biểu mẫu và sử dụng nhiều bộ nhớ nếu 3 lớn.
Gilles 'SO- ngừng trở nên xấu xa'

1
@ alpha_989 Trong cú pháp giống như sh, bạn cần dosau ));. Zsh cũng chấp nhận một cú pháp khác for ((…)); COMMANDtrong đó COMMANDlà một lệnh đơn. Đó là lý do tại sao nó chấp nhận for ((i = 1; i<100; i++)); ghi show $i | grep "log". Khi nó nhìn thấy donesau đó, nó phàn nàn vì không có dokết thúc. Xem các hình thức thay thế cho các lệnh phức tạp trong hướng dẫn sử dụng .
Gilles 'SO- ngừng trở nên xấu xa'
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.