2013-04-02 14 views
7

Ho un semplice script bash, simple.sh, come segue:Perché non posso passare una directory come argomento ad un ciclo for in bash?

#/usr/local/bin/bash 
for i in $1 
    do 
     echo The current file is $i 
    done 

Quando eseguo con il seguente argomento:

./simple.sh /home/test/* 

sarebbe solo la stampa e la lista fuori il primo file che si trova nella directory.

Tuttavia, se cambio simple.sh a:

#/usr/local/bin/bash 
DIR=/home/test/* 
for i in $DIR 
    do 
     echo The current file is $i 
    done 

sarebbe correttamente stampare i file all'interno della directory. Qualcuno può aiutare a spiegare perché l'argomento passato non sta mostrando lo stesso risultato?

risposta

8

Se si prende "$ 1", è il primo file/directory, che è possibile! si dovrebbe fare in questo modo:

for i in "[email protected]" 
do 
    echo The current file is ${i} 
done 

Se lo si esegue con:

./simple.sh * 

Essi si elencano tutti i file del dizionario vero e proprio

"$ 1" è alfabetico il primo file/directory della directory corrente, e nel ciclo for, il valore di "i" sarebbe eg a1.sh e poi sarebbero usciti dal ciclo for! Se lo fai:

DIR=/home/<s.th.>/* 

si salva il valore di tutti i file/directory in DIR!

+1

Questo dovrebbe essere '" $ @ "' quindi funziona anche per i file con spazi nel nome. – Jens

+0

Sì, ovviamente questo dovrebbe essere come "$ @" ... – Oni1

+0

E con '" $ i "' lo spazio bianco viene mantenuto anche nel messaggio. Si tratta di dettagli :-) – Jens

-2

Come su lista file manully invece di utilizzare *:

#/usr/local/bin/bash 
    for i in $(ls $1) 
    do 
     echo The current file is $i 
    done 

e digitare

./simple.sh /home/test/ 
+1

Questo non funzionerà se uno dei nomi di file nella directory contiene spazi vuoti. – chepner

1

Questo è più portabile come si arriva, non ha forchette inutile ls e corre con un minimo di CPU cicli sprecati:

#!/bin/sh 
cd $1 
for i in *; do 
    echo The current file is "$i" 
done 

Esegui come ./simple.sh /home/test

+0

"il minimo di cicli CPU sprecati" sarebbe probabilmente C piuttosto che bash, tbh ;-) – Kos

+0

No; non quando si tiene conto dell'impronta di carbonio, uh, l'impronta del ciclo della compilation :-) – Jens

1

Lo script non riceve "/ home/test/*" come argomento; la shell espande il patter sull'elenco di file corrispondenti e la shell riceve più argomenti, uno per file corrispondente. Citando l'argomento funziona:

./simple.sh "/home/test/*" 

La modifica di utilizzare DIR=/home/test/* ha fatto quello che ti aspettavi, perché la generazione nome del file non viene eseguita sul RHS di un assegnamento di variabile. Quando hai lasciato $DIR non quotato nel ciclo for, il motivo è stato espanso nell'elenco dei file corrispondenti.

Problemi correlati