Bash „for” loop bez części „in foo bar…”


25

Ostatnio patrzyłem na kod, który mnie pomylił, ponieważ działa, a nie spodziewałem się, że to zrobi. Kod ogranicza się do tego przykładu

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

Gdy jest uruchamiany z argumentami wiersza poleceń, drukuje je

$ ./test a b c
a
b
c

To jest (dla mnie) nieoczekiwane. Dlaczego nie powoduje to błędu, ponieważ varjest niezdefiniowany? Czy stosowanie tego jest uważane za „dobrą praktykę”?

Odpowiedzi:


27

forzapętla pętle na parametrach pozycyjnych, jeśli żadna in value1 value2...część nie jest określona we wszystkich powłokach podobnych do Bourne'a.

Tak było już w przypadku powłoki Bourne'a z późnych lat 70., chociaż w powłoce Bourne'a należałoby to pominąć ;(możesz także użyć for i do(z wyjątkiem niektórych starych wersji jesionowych, w których przed nową linią potrzebujesz do)).

Zobacz Jaki jest cel słowa kluczowego „do” w Bash dla pętli? aby uzyskać więcej informacji, w tym bardziej zaskakujące warianty.

Robić:

for i
do
  something with "$i"
done

jest dobrą praktyką. Jest nieco bardziej przenośny / niezawodny niż zwykle równoważny:

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

dla których powłoka Bourne'a, ksh88 ma pewne problemy pod pewnymi warunkami (np. kiedy $#jest 0 w niektórych wersjach powłoki Bourne'a (które ${1+"$@"}zamiast tego "$@"mogą działać) lub gdy $IFSnie zawiera znaku spacji w Bourne i ksh88), lub gdy nounsetopcja jest włączona i $#jest 0 w niektórych wersjach niektórych muszli oraz bash( ponownie ${1+"$@"}jako obejście ).


Musiałem przeczytać to trzy razy, zanim mój mózg postanowił przestać edytować powtarzającą się „pętlę” na początku
Three Diag

20

To jest domyślne zachowanie, tak. Jest to udokumentowane w helptego forsłowa kluczowego:

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.

Tak więc, jeśli nie dać mu listę iteracyjne nad, to domyślnie iteracji nad $@tablica parametrów pozycyjnych ( a, ba cna swoim przykładzie).

To zachowanie jest zdefiniowane przez POSIX, więc tak, uważa się je za „dobrą praktykę”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.