Quelle est la différence entre du -sh * et du -sh ./* ?
 Remarque :Ce qui m'intéresse, c'est le * et ./* pièces.
Réponse acceptée :
$ touch ./-c $'an12tb' foo $ du -hs * 0 a 12 b 0 foo 0 total
 Comme vous pouvez le voir, le -c le fichier a été pris en option pour du et n'est pas signalé (et vous voyez le total ligne à cause de du -c ). Aussi, le fichier nommé an12tb nous fait penser qu'il existe des fichiers appelés a et b .
$ du -hs -- *
0       a
12      b
0       -c
0       foo
 
 C'est mieux. Au moins cette fois -c n'est pas considéré comme une option.
$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo
 
 C'est même mieux. Le ./ le préfixe empêche -c d'être pris en option et l'absence de ./ avant b dans la sortie indique qu'il n'y a pas de b fichier là-dedans, mais il y a un fichier avec un caractère de nouvelle ligne (mais voir ci-dessous pour d'autres digressions à ce sujet).
 Il est recommandé d'utiliser le ./ préfixe si possible, et sinon et pour des données arbitraires, vous devriez toujours utiliser :
cmd -- "$var"
 ou :
cmd -- $patterns
 
 Si cmd ne prend pas en charge -- pour marquer la fin des options, il faut le signaler comme bogue à son auteur (sauf quand c'est par choix et documenté comme pour echo ).
 Il y a des cas où ./* résout les problèmes qui -- n'a pas. Par exemple :
awk -f file.awk -- *
 
 échoue s'il existe un fichier nommé a=b.txt dans le répertoire courant (définit la variable awk a vers b.txt au lieu de lui dire de traiter le fichier).
awk -f file.awk ./*
 
 N'a pas le problème car ./a n'est pas un nom de variable awk valide, donc ./a=b.txt n'est pas considéré comme une affectation de variable.
cat -- * | wc -l
 
 échoue s'il existe un fichier appelé - dans le répertoire courant, comme cela indique cat lire depuis son stdin (- est spécial pour la plupart des utilitaires de traitement de texte et pour cd /pushd ).
cat ./* | wc -l
 
 est OK car ./- n'est pas spécial pour cat .
Des choses comme :
grep -l -- foo *.txt | wc -l
 
 pour compter le nombre de fichiers contenant foo sont erronés car ils supposent que les noms de fichiers ne contiennent pas de caractères de nouvelle ligne (wc -l compte les caractères de saut de ligne, ceux générés par grep pour chaque fichier et ceux dans les noms de fichiers eux-mêmes). Vous devriez utiliser à la place :
grep -l foo ./*.txt | grep -c /
 
 (en comptant le nombre de / caractères est plus fiable car il ne peut y en avoir qu'un par nom de fichier).
 Pour grep récursif , l'astuce équivalente consiste à utiliser :
grep -rl foo .//. | grep -c //
 
 ./* peut cependant avoir des effets secondaires indésirables.
cat ./*
 
 ajoute deux caractères supplémentaires par fichier, ce qui vous ferait atteindre plus tôt la limite de la taille maximale des arguments + environnement. Et parfois, vous ne voulez pas que ./ à signaler dans la sortie. Comme :
grep foo ./*
 Renvoie :
./a.txt: foobar
 au lieu de :
a.txt: foobar
 Digressions supplémentaires
. J'ai l'impression que je dois développer cela ici, suite à la discussion dans les commentaires.
$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo
 
 Ci-dessus, ce ./ marquer le début de chaque fichier signifie que nous pouvons clairement identifier où chaque nom de fichier commence (à ./ ) et où il se termine (à la nouvelle ligne avant le prochain ./ ou la fin de la sortie).
 Cela signifie que la sortie de du ./* , contrairement à celle de du -- * ) peut être analysé de manière fiable, mais pas aussi facilement dans un script.
Cependant, lorsque la sortie est envoyée à un terminal, il existe de nombreuses autres façons dont un nom de fichier peut vous tromper :
-  
Les caractères de contrôle, les séquences d'échappement peuvent affecter la façon dont les choses sont affichées. Par exemple,
rdéplace le curseur au début de la ligne,bdéplace le curseur vers l'arrière,e[Cvers l'avant (dans la plupart des terminaux)… -  
de nombreux caractères sont invisibles sur un terminal en commençant par le plus évident :le caractère espace.
 -  
Certains caractères Unicode ressemblent exactement à la barre oblique dans la plupart des polices
$ printf 'u002f u2044 u2215 u2571 u29F8n' / ⁄ ∕ ╱ ⧸ 
(voir comment ça se passe dans votre navigateur).
Un exemple :
$ touch x 'x ' $'ybx' $'xn0t.u2215x' $'yr0t.e[Cx'
$ ln x y
$ du -hs ./*
0       ./x
0       ./x
0       ./x
0       .∕x
0       ./x
0       ./x
 
 Beaucoup de x ‘s mais y est manquant.
 Certains outils comme GNU ls remplacerait les caractères non imprimables par un point d'interrogation (notez que ∕ (U+2215) est cependant imprimable) lorsque la sortie va à un terminal. GNU du pas.
Il existe des moyens de les faire se révéler :
$ ls
x  x   x?0?.∕x  y  y?0?.?[Cx  y?x
$ LC_ALL=C ls
x  x?0?.???x  x   y  y?x  y?0?.?[Cx
 
 Découvrez comment ∕ tourné vers ??? après avoir dit ls que notre jeu de caractères était ASCII.
$ du -hs ./* | LC_ALL=C sed -n l0t./x$0t./x $0t./x$0t.342210225x$0t./yr0t.