Bash Bash cho vòng lặp mà không có một phần tử trong phần foo


25

Gần đây tôi đã xem xét một số mã làm tôi bối rối vì nó hoạt động và tôi không mong đợi nó. Mã giảm xuống ví dụ này

#!/bin/bash
for var;
do
  echo "$var"
done

Khi chạy với các đối số dòng lệnh được in chúng

$ ./test a b c
a
b
c

Chính điều này, đó là (với tôi) bất ngờ. Tại sao điều này không dẫn đến một lỗi vì varkhông xác định? Được sử dụng này được coi là "thực hành tốt"?

Câu trả lời:


27

forvòng lặp trên các tham số vị trí nếu không có in value1 value2...phần nào được chỉ định trong tất cả các shell giống như Bourne.

Đó đã là trường hợp trong vỏ Bourne từ cuối những năm 70, mặc dù trong vỏ Bourne, bạn cần bỏ qua điều đó ;(bạn cũng có thể sử dụng for i do(ngoại trừ trong một số phiên bản tro cũ, nơi bạn cần một dòng mới trước do)).

Xem mục đích của từ khóa "làm" trong Bash cho các vòng lặp là gì? để biết thêm thông tin bao gồm các biến thể đáng ngạc nhiên hơn .

Đang làm:

for i
do
  something with "$i"
done

là thực hành tốt. Nó hơi di động / đáng tin cậy hơn so với thường tương đương:

for i in "$@"; do
  something with "$i"
done

trong đó vỏ Bourne, ksh88 có một số vấn đề trong một số điều kiện (như khi nào $#là 0 trong một số phiên bản của vỏ Bourne ( ${1+"$@"}thay vì "$@"có thể hoạt động xung quanh) hoặc khi $IFSkhông chứa ký tự khoảng trắng trong Bourne và ksh88) hoặc khi các nounsettùy chọn được kích hoạt và $#là 0 trong một số phiên bản của một số vỏ bao gồm bash( một lần nữa với ${1+"$@"}một công việc xung quanh ).


Phải đọc ba lần này trước khi não tôi quyết định ngừng chỉnh sửa 'vòng lặp' lặp đi lặp lại khi bắt đầu
Three Diag

20

Đây là hành vi mặc định, vâng. Nó được diễn tả trong helpcác fortừ khóa:

terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

    Exit Status:
    Returns the status of the last command executed.

Vì vậy, khi bạn không cung cấp cho nó một danh sách để lặp kết thúc, nó sẽ mặc định iterating trên $@, mảng tham số vị trí ( a, bctrong ví dụ của bạn).

Và hành vi này được xác định bởi POSIX nên có, nó được coi là "thực hành tốt" cho đến nay.

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.