Bash“ for” loop โดยไม่มีส่วน“ in foo bar …”


25

ฉันเพิ่งดูรหัสบางอย่างที่สับสนฉันเพราะมันใช้งานได้และฉันไม่ได้คาดหวัง รหัสย่อมาจากตัวอย่างนี้

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

เมื่อรันด้วยอาร์กิวเมนต์บรรทัดคำสั่งจะพิมพ์ออกมา

$ ./test a b c
a
b
c

นี่คือสิ่งที่คาดไม่ถึงสำหรับฉัน เหตุใดจึงไม่ส่งผลให้เกิดข้อผิดพลาดเนื่องจากvarไม่ได้กำหนดไว้? การใช้สิ่งนี้ถือว่าเป็น 'การปฏิบัติที่ดี' หรือไม่?

คำตอบ:


27

forวนซ้ำลูปในพารามิเตอร์ตำแหน่งหากไม่มีin value1 value2...ส่วนใดถูกระบุในเชลล์เหมือน Bourne ทั้งหมด

นั่นเป็นกรณีในเชลล์เป้าหมายจากช่วงปลายยุค 70 แม้ว่าในเชลล์เป้าหมายคุณจะต้องละเว้นสิ่งนั้น;(คุณสามารถใช้for i do(ยกเว้นในรุ่นเถ้าเก่าบางรุ่นที่คุณต้องการขึ้นบรรทัดใหม่ก่อนdo))

ดูวัตถุประสงค์ของคำหลัก "ทำ" ใน Bash สำหรับลูปคืออะไร สำหรับข้อมูลเพิ่มเติมรวมถึงสายพันธุ์ที่น่าแปลกใจมากขึ้น

การทำ:

for i
do
  something with "$i"
done

เป็นการปฏิบัติที่ดี มันพกพา / ไว้ใจได้มากกว่าปกติเล็กน้อย:

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

ซึ่งเชลล์ Bourne, ksh88 มีปัญหาบางอย่างภายใต้เงื่อนไขบางอย่าง (เช่นเมื่อ$#เป็น 0 ในบางรุ่นของเชลล์เป้าหมาย (ซึ่ง${1+"$@"}แทนที่จะ"$@"สามารถแก้ไขได้) หรือเมื่อ$IFSไม่มีอักขระช่องว่างใน Bourne และ ksh88) หรือเมื่อnounsetตัวเลือกที่ถูกใช้งานและ$#เป็น 0 ในบางรุ่นของเปลือกหอยบางส่วนรวมถึงbash( อีกครั้งกับ${1+"$@"}เป็นงานรอบ )


ต้องอ่านสามครั้งนี้ก่อนที่สมองของฉันตัดสินใจที่จะหยุดการแก้ไข 'วนซ้ำ' ที่เริ่มต้นซ้ำ
Three Diag

20

นี่คือพฤติกรรมเริ่มต้นใช่ มันเป็นเอกสารในhelpของforคำหลัก:

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.

ดังนั้นเมื่อคุณไม่ให้มันรายการที่ต้องย้ำมากกว่าก็จะเริ่มต้นทำซ้ำมากกว่า$@อาร์เรย์ของพารามิเตอร์ตำแหน่งนี้ ( a, bและcในตัวอย่างของคุณ)

และพฤติกรรมนี้ถูกกำหนดโดย POSIXดังนั้นใช่ถือเป็น "แนวปฏิบัติที่ดี" เท่าที่จะทำได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.