Chi tratta (interpreta) il * in
echo *
L'eco vede la stella o la shell occuparsene e restituisce un elenco di nomi di file?
Che dire
cp temp temp*
Chi tratta (interpreta) il * in
echo *
L'eco vede la stella o la shell occuparsene e restituisce un elenco di nomi di file?
Che dire
cp temp temp*
Risposte:
bash (o qualunque cosa tu usi come shell), è la prima cosa a leggere qualsiasi input e inizierà a interpretare caratteri speciali come ?
e *
. *
viene espanso a qualsiasi corrispondenza nel CWD , il che significa che l'asterisco viene sostituito da tali corrispondenze.
Nella maggior parte dei casi, ciò è abbastanza avanzato, ma di volta in volta può portare ad alcuni casi confusi.
Considera quanto segue. Una directory ha questo contenuto:
Se poi scrivi mv *
qualcosa che sembra strano, succede: test3
c'è, ma il resto è sparito. Anche se all'inizio è strano, ha senso una volta capito a cosa passa effettivamente la bash mv
. A causa dell'asterisco, bash interpreta mv *
as mv test test1 test2 test3
, e quando mv ottiene quell'elenco, supporrà che l'ultimo argomento sia la destinazione, che è dove tutti i file sarebbero stati spostati.
Per quanto riguarda i comandi che hai elencato:
echo *
può funzionare come un uomo povero ls
. La shell espanderà l'asterisco a qualunque cosa si trovi in quella directory, e come sono sicuro che già sapete, echo
letteralmente farà eco a tutto ciò che Bash gli ha passato come argomentazioni.cp temp temp*
si comporterà in qualche modo come il mv
comando che ho descritto sopra, a meno che non vi sia una sola directory denominata temp, nel qual caso il nome di origine e di destinazione è lo stesso, cioè non farà nulla.*
invece di ls
. Ad esempio, for f in *; do
è più affidabile che for f in $(ls)
se un nome file contiene spazi bianchi o un carattere glob. (Tuttavia, fallirà se non ci sono file nel CWD, quindi è necessario controllare per quel caso.)
shopt nullglob
serve.
echo *
, quel trucco può salvarti in alcuni casi.
Come già detto, la shell si espande, *
quindi echo
ricevi come argomenti qualunque cosa la shell trovi nella directory corrente. Tuttavia, si noti che se l'espansione non porta a nulla, ovvero in questo caso se la directory non contiene file non nascosti, *
viene lasciata invariata e passata così com'è al comando chiamato (a meno che non vengano utilizzate opzioni non standard con alcune shell come bash
.) echo *
non si comporterà poi come un povero ls
perché il primo non stampa nulla mentre il secondo stampa *
.
Allo stesso modo, cp /tmp/temp temp*
creerà un file denominato temp*
nella directory corrente se non esiste ancora almeno un file con il nome che inizia con temp
.
Infine, se vuoi *
che sia passato invariato in ogni caso, puoi proteggerlo dall'espansione usando virgolette singole '*'
, doppie virgolette "*"
o barra rovesciata \*
.
In Bash, la shell se ne occupa. Lo vedi se provi anche *
senza eco
Sulla base di alcuni commenti, suggerirei quando si esegue * INVIO, di creare una directory e utilizzare il comando touch per creare alcuni file e assicurarsi che nessuno di essi, o almeno assicurarsi che il primo in ordine alfabetico, non sia il nome di qualsiasi script o comando nel percorso.
$ *
bash: a: command not found
$ echo *
a a.aa a.ab a.b a.htm a.tx
Quindi ls *
è un po 'un cliché
In Windows, *
è gestito dal comando, quindi dir *.*
non è un cliché.
Nota- Vedendo alcuni commenti, aggiungerei, c'è il rischio di eseguire * quindi INVIO. Se hai un file chiamato rm che è il primo nella lista delle directory, allora è pericoloso perché qualsiasi cosa dopo sarebbe stata cancellata. Inoltre, e questo è meno improbabile, se il primo file nell'elenco di directory è il nome di uno script nel percorso, verrà eseguito.
rm
, ovviamente.
-rf
? Ho provato touch -rf
e touch \-rf
ma non lo sta creando.
-rf
? (Capisco il pericolo di un file chiamato rm e un file chiamato -rf, e il problema di digitare * e premere
La shell esegue diverse espansioni prima che gli argomenti vengano passati al comando.
Vedi anche https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion
Non specifico per bash, vedi http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01