Sous Linux, j'utilise stat --format="%s" FILE
, mais Solaris auquel j'ai accès n’a pas de commande stat. Que devrais-je utiliser alors?
J'écris des scripts Bash et je ne peux pas installer de nouveau logiciel sur le système.
J'ai déjà envisagé d'utiliser:
Perl -e '@x=stat(shift);print $x[7]' FILE
ou même:
ls -nl FILE | awk '{print $5}'
Mais aucun de ceux-ci ne semble raisonnable - exécuter Perl uniquement pour obtenir la taille du fichier? Ou exécuter 2 commandes pour faire la même chose?
wc -c < filename
(abréviation de Nombre de mots, -c
affiche le nombre d'octets) est une solution portable POSIX . Seul le format de sortie peut ne pas être uniforme sur toutes les plates-formes, car certains espaces peuvent être préfixés (comme c'est le cas pour Solaris).
N'omettez pas la redirection d'entrée. Lorsque le fichier est passé en argument, le nom du fichier est imprimé après le nombre d'octets.
Je craignais que cela ne fonctionne pas pour les fichiers binaires, mais cela fonctionne correctement sous Linux et Solaris. Vous pouvez l'essayer avec wc -c < /usr/bin/wc
. De plus, les utilitaires POSIX sont garantis pour gérer les fichiers binaires , sauf indication contraire explicite.
J'ai fini par écrire mon propre programme (très petit) pour afficher uniquement la taille. Plus d'informations ici: http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
Les deux méthodes les plus propres à mon avis avec les outils Linux courants sont les suivantes:
$ stat -c %s /usr/bin/stat
50000
$ wc -c < /usr/bin/wc
36912
Mais je ne veux tout simplement pas taper des paramètres ou transmettre la sortie simplement pour obtenir une taille de fichier, alors j'utilise ma propre taille de fichier.
Même si du
imprime généralement l'utilisation du disque et non la taille réelle des données, GNU coreutils du
peut imprimer la "taille apparente" du fichier en octets:
du -b FILE
Mais cela ne fonctionnera pas sous BSD, Solaris, macOS, ...
Enfin, j’ai décidé d’utiliser ls et le développement de tableaux bash:
TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}
ce n'est pas vraiment agréable, mais au moins, il ne fait que 1 fork + execve, et il ne s'appuie pas sur un langage de programmation secondaire (Perl/Ruby/python/peu importe)
Solution la plus rapide entre plates-formes (utilise uniquement un fork () pour ls, ne tente pas de compter les caractères réels, ne génère pas de mots inutiles: awk, Perl, etc.).
Testé sous MacOS, Linux - peut nécessiter des modifications mineures pour Solaris:
__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"
Si nécessaire, simplifiez les arguments ls et ajustez le décalage dans $ {__ ln [3]}.
Remarque: suivra les liens symboliques.
Si vous utilisez find
de GNU fileutils:
size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )
Malheureusement, les autres implémentations de find
ne supportent généralement pas -maxdepth
, ni -printf
. C’est le cas, par exemple, de Solaris et macOS find
.
Lors du traitement ls -n
sortie, vous pouvez utiliser les arguments de position, qui constituent le seul tableau et sont les seules variables locales dans le standard Shell. Enveloppez l'écrasement des arguments de position dans une fonction pour conserver les arguments d'origine dans votre script ou votre fonction.
getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE
Cela divise la sortie de ln -dn
en fonction des paramètres de variable d’environnement IFS
actuels, l’assigne aux arguments de position et fait écho au cinquième. Le -d
s'assure que les répertoires sont gérés correctement et que le -n
_ assure que les noms d’utilisateur et de groupe n’ont pas besoin d’être résolus, contrairement à -l
. En outre, les noms d'utilisateurs et de groupes contenant des espaces pourraient théoriquement rompre la structure de ligne attendue; ils sont généralement refusés, mais cette possibilité oblige le programmeur à s'arrêter et à réfléchir.
Vous pouvez utiliser la commande find
pour obtenir un ensemble de fichiers (ici, les fichiers temporaires sont extraits). Ensuite, vous pouvez utiliser la commande du
pour obtenir la taille de fichier de chaque fichier sous une forme lisible par l'homme à l'aide de -h
_ commutateur.
find $HOME -type f -name "*~" -exec du -h {} \;
SORTIE:
4.0K /home/turing/Desktop/JavaExmp/TwoButtons.Java~
4.0K /home/turing/Desktop/JavaExmp/MyDrawPanel.Java~
4.0K /home/turing/Desktop/JavaExmp/Instream.Java~
4.0K /home/turing/Desktop/JavaExmp/RandomDemo.Java~
4.0K /home/turing/Desktop/JavaExmp/Buff.Java~
4.0K /home/turing/Desktop/JavaExmp/SimpleGui2.Java~
Votre premier exemple Perl ne me semble pas déraisonnable.
C'est pour des raisons de ce type que j'ai migré de l'écriture de scripts Shell (en bash/sh, etc.) à l'écriture de tous les scripts sauf les plus triviaux de Perl. Je me suis rendu compte que je devais lancer Perl pour des besoins particuliers, et au fur et à mesure que je le faisais, je me suis rendu compte que l'écriture des scripts en Perl était probablement plus puissante (en termes de langage et du grand nombre de bibliothèques disponibles via - CPAN ) et un moyen plus efficace de réaliser ce que je voulais.
Notez que d'autres langages de script Shell (par exemple, python/Ruby) auront sans aucun doute des fonctionnalités similaires, et vous voudrez peut-être les évaluer pour vos besoins. Je ne discute que de Perl car c'est le langage que j'utilise et que je connais bien.