GNU/Linux >> Linux Esercitazione >  >> Linux

Il risultato di Ls * , Ls ** e Ls ***?

So di usare il comando ls elencherà tutte le directory. Ma cosa significa ls * comando fare? L'ho usato e elenca solo le directory. La stella davanti a ls significa quanto in profondità elencherà le directory?

Risposta accettata:

ls elenca i file e il contenuto delle directory che viene passato come argomenti e, se non viene fornito alcun argomento, elenca la directory corrente. Può anche essere passato un certo numero di opzioni che influenzano il suo comportamento (vedi man ls per i dettagli).

Se ls viene passato un argomento chiamato * , cercherà un file o una directory chiamata * nella directory corrente ed elencarlo come qualsiasi altro. ls non tratta il * carattere in modo diverso da qualsiasi altro.

Tuttavia, se ls * è un guscio riga di comando, ovvero codice nel linguaggio di una shell Unix , quindi la shell espanderà quel * secondo il suo globbing (indicato anche come Generazione di nomi di file o Espansione nome file/percorso ) regole.

Sebbene shell diverse supportino diversi operatori di globbing, la maggior parte di esse concorda sul più semplice * . * come pattern significa un numero qualsiasi di caratteri, quindi * come glob si espanderà all'elenco dei file nelle directory correnti che corrispondono a quel modello. C'è un'eccezione, tuttavia, che un punto iniziale (. ) il carattere in un nome di file deve essere abbinato in modo esplicito, quindi * in realtà si espande all'elenco di file e directory che non iniziano con . (in ordine lessicale).

Ad esempio, se la directory corrente contiene i file chiamati . , .. , .foo , -l e foo bar , * verrà espanso dalla shell a due argomenti da passare a ls :-l e foo bar , quindi sarà come se avessi digitato:

ls -l "foo bar"

o

'ls' "-l" foo bar

Quali sono tre modi per eseguire esattamente lo stesso comando. In tutti e 3 i casi, il ls comando (che probabilmente verrà eseguito da /bin/ls da una ricerca di directory menzionate in $PATH ) verranno passati quei 3 argomenti:“ls”, “-l” e “foo bar”.

Per inciso, in questo caso, ls tratterà il primo (in senso stretto secondo ) uno come opzione.

Ora, come ho detto, shell diverse hanno operatori di globbing diversi. Alcuni decenni fa, zsh introdotto il **/ operator¹ che significa corrispondere a qualsiasi livello di sottodirectory, abbreviazione di (*/)# e ***/ che è lo stesso tranne per il fatto che segue i collegamenti simbolici durante la discesa delle directory.

Alcuni anni fa (luglio 2003, ksh93o+ ), ksh93 ha deciso di copiare quel comportamento ma ha deciso di renderlo facoltativo e ha coperto solo il ** caso (non *** ). Inoltre, mentre ** da solo non era speciale in zsh ² (significava proprio come * come in altre shell tradizionali da ** indica un numero qualsiasi di caratteri seguito da un numero qualsiasi di caratteri), in ksh93, ** significava lo stesso di **/* (quindi qualsiasi file o directory al di sotto di quello corrente (esclusi i file nascosti)³.

bash copiato ksh93 qualche anno dopo (febbraio 2009, bash 4.0), con la stessa sintassi ma una sfortunata differenza:** di bash era come zsh 's *** , ovvero seguiva i collegamenti simbolici quando ricorreva nelle sottodirectory che generalmente non è quello che vuoi che faccia e può avere cattivi effetti collaterali. È stato in parte risolto in bash-4.3 in quanto i collegamenti simbolici erano ancora seguiti, ma la ricorsione si è fermata lì. È stato completamente risolto in 5.0.

yash aggiunto ** nella versione 2.0 nel 2008, abilitato con il extended-glob opzione. La sua implementazione è più vicina a zsh è in quel ** da solo non è speciale. Nella versione 2.15 (2009), ha aggiunto *** come in zsh e due delle sue estensioni:.** e .*** per includere directory nascoste durante la ricorrenza (in zsh , il D qualificatore globale (come in **/*(D) ) prenderà in considerazione i file e le directory nascosti, ma se vuoi solo attraversare le directory nascoste ma non espandere i file nascosti, è necessario ((*|.*)/)#* o **/[^.]*(D) ).

Correlati:simulazione del circuito di ritaglio che produce risultati inaspettati?

Il guscio di pesce supporta anche ** . Come la versione precedente di bash , segue i collegamenti simbolici quando discende l'albero delle directory. In quella shell però **/* non è uguale a ** . ** è più un'estensione di * che può estendersi su più directory. In fish , **/*.c corrisponderà a a/b/c.c ma non a.c , mentre a**.c corrisponderà a a.c e ab/c/d.c e zsh 's **/.* per esempio deve essere scritto .* **/.* . Ecco, *** è inteso come ** seguito da * quindi lo stesso di ** .

tcsh aggiunto anche un globstar opzione in V6.17.01 (maggio 2010) e supporta entrambi ** e *** alla zsh .

Quindi in tcsh , bash e ksh93 , (quando l'opzione corrispondente è abilitata (globstar )) o fish , ** espande tutti i file e le directory sotto quello corrente e *** è uguale a ** per fish , un collegamento simbolico che attraversa ** per tcsh con globstar e lo stesso di * in bash e ksh93 (sebbene non sia impossibile che le versioni future di quelle shell attraversino anche i collegamenti simbolici).

Sopra, avrai notato la necessità di assicurarti che nessuna delle espansioni venga interpretata come un'opzione. Per questo, faresti:

ls -- *

Oppure:

ls ./*

Ci sono alcuni comandi (non importa per ls ) dove è preferibile la seconda poiché anche con il -- alcuni nomi di file possono essere trattati in modo speciale. È il caso di - per la maggior parte delle utilità di testo, cd e pushd e nomi di file che contengono = carattere per awk per esempio. ./ anteposto a tutti gli argomenti rimuove il loro significato speciale (almeno per i casi sopra menzionati).

Va anche notato che la maggior parte delle shell ha un numero di opzioni che influenzano il comportamento del globbing (come se i file dot vengono ignorati o meno, l'ordine di ordinamento, cosa fare se non c'è corrispondenza...), vedi anche il $FIGNORE parametro in ksh

Inoltre, in ogni shell tranne csh , tcsh , fish e zsh , se il modello di globbing non corrisponde a nessun file, il modello viene passato come argomento non espanso che causa confusione e possibilmente bug. Ad esempio, se non ci sono file non nascosti nella directory corrente

ls *

In realtà chiamerà ls con i due argomenti ls e * . E poiché non esiste alcun file, quindi nessuno si chiama * in entrambi i casi vedrai un messaggio di errore da ls (non la shell) come:ls: cannot access *: No such file or directory , che è noto per far pensare alla gente che fosse ls in realtà stava espandendo i glob.

Il problema è ancora peggiore in casi come:

rm -- *.[ab]

Se non è presente *.a*.b file nella directory corrente, potresti finire per eliminare un file chiamato *.[ab] per errore (csh , tcsh e zsh segnalerebbe una nessuna corrispondenza errore e non chiamerebbe rm (e fish non supporta il [...] caratteri jolly)).

Se vuoi passare un * letterale a ls , devi citare quel * carattere in qualche modo come in ls * o ls '*' o ls "*" . Nelle shell simili a POSIX, il globbing può essere disabilitato del tutto usando set -o noglob o set -f (quest'ultimo non funziona in zsh a meno che in sh /ksh emulazione).

Correlati:Php:mysql_field_seek — Imposta il puntatore del risultato su un offset di campo specificato

.


Linux
  1. Il comando Sed di Linux:utilizzo ed esempi

  2. Come controllare la versione del sistema operativo e di Linux

  3. La differenza tra [[ $a ==Z* ]] e [ $a ==Z* ]?

  4. La differenza tra Getty e Agety?

  5. Ottieni il complemento del risultato di un comando Ls?

Linux sul mainframe:allora e adesso

Qual è la differenza tra Linux e Unix?

Inode e il filesystem di Linux

Le 20 migliori guide ed esercitazioni per amministratori di sistema

E la migliore distribuzione del 2019 è...

Linux Script per verificare se il processo è in esecuzione e agire sul risultato