En Linux, lo uso stat --format="%s" FILE, pero Solaris al que tengo acceso no tiene comando stat. ¿Qué debo usar entonces?
Estoy escribiendo scripts Bash y realmente no puedo instalar ningún software nuevo en el sistema.
Ya he considerado usar:
perl -e '@x=stat(shift);print $x[7]' FILE
o incluso:
ls -nl FILE | awk '{print $5}'
Pero ninguno de estos parece sensato: ¿ejecutar Perl solo para obtener el tamaño del archivo? ¿O ejecutar 2 comandos para hacer lo mismo?

Respuestas:
wc -c < filename(abreviatura de recuento de palabras,-cimprime el recuento de bytes) es una solución POSIX portátil . Solo el formato de salida puede no ser uniforme en todas las plataformas, ya que algunos espacios pueden estar precedidos (como es el caso de Solaris).No omita la redirección de entrada. Cuando el archivo se pasa como argumento, el nombre del archivo se imprime después del recuento de bytes.
Me preocupaba que no funcionara con archivos binarios, pero funciona bien tanto en Linux como en Solaris. Puedes probarlo con
wc -c < /usr/bin/wc. Además, las utilidades POSIX están garantizadas para manejar archivos binarios , a menos que se especifique lo contrario explícitamente.fuente
wc -c < filesi no desea que aparezca el nombre del archivo.wcen una canalización deberead()todo el flujo contar los bytes. Las solucionesls/awk(y similares) usan una llamada al sistema para obtener el tamaño, que debería ser tiempo lineal (versus O (tamaño))wchaber sido muy lento la última vez que hice eso en un disco duro lleno. Fue lo suficientemente lento como para poder volver a escribir el guión antes de que terminara el primero, vine aquí para recordar cómo lo hice jajaja.wc -c; se ve mucho más ordenado perols+awkes mejor para la velocidad / uso de recursos. Además, solo quería señalar que en realidad también necesita postprocesar los resultadoswcporque en algunos sistemas tendrá espacios en blanco antes del resultado, que es posible que deba eliminar antes de poder hacer comparaciones.wc -ces genial, pero no funcionará si no tiene acceso de lectura al archivo.Terminé escribiendo mi propio programa (realmente pequeño) para mostrar solo el tamaño. Más información aquí: http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
En mi opinión, las dos formas más limpias con las herramientas comunes de Linux son:
Pero simplemente no quiero escribir parámetros o canalizar la salida solo para obtener un tamaño de archivo, así que estoy usando mi propio bfsize.
fuente
states una opción para ellos.wc -ctoma 4090 mseg en un archivo de 10 MB en lugar de "0" msegstat -c %s, así que estoy de acuerdo en que es útil tener soluciones alternativas incluso cuando no responden la pregunta exacta planteada.stat -c %s /usr/bin/statstat: illegal option -- cusage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]Aunque
dunormalmente imprime el uso del disco y no el tamaño real de los datos, las coreutils de GNUdupueden imprimir el "tamaño aparente" del archivo en bytes:Pero no funcionará con BSD, Solaris, macOS, ...
fuente
brew install coreutilsygdu -blogrará el mismo efectowcnecesita leer todo el archivo antes de dar un resultado,dues inmediato.du -ben un contexto completamente diferente en ladurazón de ser .lstatllamada, por lo que su rendimiento no depende del tamaño del archivo. Más corto questat -c '%s', pero menos intuitivo y funciona de manera diferente para las carpetas (imprime el tamaño de cada archivo dentro).dupuede acercarse usandodu -A -B1, pero aún imprime el resultado en múltiplos de 1024B bloques. No logré que imprimiera el recuento de bytes. Incluso la configuraciónBLOCKSIZE=1en el entorno no ayuda, porque entonces se utilizan bloques 512B.Finalmente decidí usar ls y la expansión de matriz bash:
no es realmente agradable, pero al menos solo hace 1 fork + execve, y no depende del lenguaje de programación secundario (perl / ruby / python / lo que sea)
fuente
ls -ln FILE | { read _ _ _ _ size _ && echo "$size"; }no necesita bifurcaciones para el segundo paso de la canalización, ya que solo usa incorporados, sino que Bash 4.2.37 en Linux bifurca dos veces (aunque solo unaexecve).read _ _ _ _ size _ <<<"$(exec ls -ln /usr/bin/wc)" && echo "$size"funciona con un solo fork y single exec, pero usa un archivo temporal para here-string. Puede hacerse portátil reemplazando here-string por here-document compatible con POSX . Por cierto, tengaexecen cuenta el en la subcapa. Sin eso, Bash realiza una bifurcación para el subshell y otra para el comando que se ejecuta dentro. Este es el caso del código que proporciona en esta respuesta. también.-les superfluo en presencia de-n. Citando POSIXlspágina de manual :-n: Active la-lopción (ELL), pero al escribir el propietario del archivo o grupo, escriba UID numérico del archivo o GID en lugar del nombre de usuario o grupo, respectivamente. Desactivar los-C,-my-xopciones.La solución más rápida multiplataforma (solo usa un solo fork () para ls , no intenta contar los caracteres reales, no genera awk, perl, etc. innecesarios).
Probado en MacOS, Linux; puede requerir una pequeña modificación para Solaris:
Si es necesario, simplifique los argumentos de ls y ajuste el desplazamiento en $ {__ ln [3]}.
Nota: seguirá los enlaces simbólicos.
fuente
Los BSD tienen
statopciones diferentes a las de GNU coreutils, pero capacidades similares.Esto funciona en macOS (probado en 10.12), FreeBSD , NetBSD y OpenBSD .
fuente
statutilidad.Al procesar la
ls -nsalida, como alternativa a las matrices de shell poco portátiles, puede usar los argumentos posicionales, que forman la única matriz y son las únicas variables locales en la shell estándar. Envuelva la sobrescritura de los argumentos posicionales en una función para preservar los argumentos originales de su script o función.Esto divide la salida de
ln -dnsegúnIFSla configuración actual de la variable de entorno, la asigna a los argumentos posicionales y se hace eco del quinto. El-dasegura que los directorios se manejen correctamente y-nasegura que los nombres de usuarios y grupos no necesitan ser resueltos, a diferencia de con-l. Además, los nombres de usuarios y grupos que contienen espacios en blanco podrían, en teoría, romper la estructura de línea esperada; por lo general, no se permiten, pero esta posibilidad aún hace que el programador se detenga y piense.fuente
Si usa
finddesde GNU fileutils:Desafortunadamente, otras implementaciones de
findnormalmente no admiten-maxdepthni-printf. Este es el caso de, por ejemplo, Solaris y macOSfind.fuente
size=$(test -f filename && find filename -printf '%s').-maxdepthobjetivo es evitar quefindsea recursivo (yastatque lo que el OP necesita reemplazar no lo es). A sufindcomando le falta un-namey eltestcomando no es necesario.findbusca en sus parámetros de forma recursiva archivos que coincidan con los criterios dados. Si los parámetros no son directorios, la recursividad es ... bastante simple. Por lo tanto, primero pruebo quefilenamees realmente un archivo ordinario existente, y luego imprimo su tamaño usandofindque no tiene ningún lugar para recurrir.find . -maxdepth 1 -type f -name filename -printf '%s'sólo funciona si el archivo está en el directorio actual y aún puede examinar cada archivo en el directorio, lo que puede ser lento. Mejor uso (¡incluso más corto!)find filename -maxdepth 1 -type f -printf '%s'.Puede usar el
findcomando para obtener un conjunto de archivos (aquí se extraen los archivos temporales). Luego, puede usar elducomando para obtener el tamaño de archivo de cada archivo en forma legible por humanos usando el-hinterruptor.SALIDA:
fuente
Tu primer ejemplo de Perl no me parece irrazonable.
Es por razones como esta que migré de escribir scripts de shell (en bash / sh, etc.) a escribir todos los scripts menos los más triviales en Perl. Descubrí que tenía que lanzar Perl para requisitos particulares y, a medida que lo hacía cada vez más, me di cuenta de que escribir los scripts en Perl era probablemente una forma más poderosa (en términos del lenguaje y la amplia gama de bibliotecas disponibles a través de CPAN ) y una forma más eficiente de lograr lo que quería.
Tenga en cuenta que otros lenguajes de secuencias de comandos de shell (por ejemplo, python / ruby) sin duda tendrán instalaciones similares, y es posible que desee evaluarlas para sus propósitos. Solo hablo de Perl porque ese es el lenguaje que uso y con el que estoy familiarizado.
fuente
si tiene Perl en su Solaris, utilícelo. De lo contrario, ls con awk es su siguiente mejor opción, ya que no tiene stat o su búsqueda no es GNU find.
fuente
Hay un truco en Solaris que he usado, si solicita el tamaño de más de un archivo, devuelve solo el tamaño total sin nombres, así que incluya un archivo vacío como / dev / null como segundo archivo:
por ejemplo, archivo de comando que desea / dev / null
No puedo recordar qué comando de tamaño funciona para ls / wc / etc; desafortunadamente no tengo una caja solaris para probarlo.
fuente
en Linux que puede usar
du -h $FILE, ¿eso también funciona en Solaris?fuente
¿Probaste du -ks | awk '{imprimir $ 1 * 1024}'. Eso podría funcionar.
fuente