maneira portátil para obter o tamanho do arquivo (em bytes) no escudo?
Pergunta
No Linux, eu uso stat --format="%s" FILE
, mas Solaris Eu tenho acesso a não ter o comando STAT. O que devo usar então?
Eu estou escrevendo scripts do Bash, e realmente não pode instalar qualquer novo software no sistema.
Eu já pensou em usar:
perl -e '@x=stat(shift);print $x[7]' FILE
ou mesmo:
ls -nl FILE | awk '{print $5}'
Mas nenhum desses olhares sensíveis - executando Perl apenas para obter o tamanho do arquivo? Ou correr 2 comandos para fazer o mesmo?
Solução
wc -c < filename
(abreviação de contagem de palavras, -c
imprime a contagem de bytes) é um portátil, solução POSIX . Apenas o formato de saída pode não ser uniforme em todas as plataformas como alguns espaços pode ser prefixado (que é o caso para Solaris).
Não se omita o redirecionamento de entrada. Quando o arquivo é passado como um argumento, o nome do arquivo é impresso após a contagem de bytes.
Eu estava preocupado que não iria funcionar para arquivos binários, mas funciona OK em ambos Linux e Solaris. Você pode experimentá-lo com wc -c < /usr/bin/wc
. Além disso, utilitários POSIX são garantido para alça arquivos binários , salvo indicação em contrário explicitamente.
Outras dicas
Acabei escrevendo meu próprio programa (muito pequeno) para exibir apenas o tamanho. Mais informações aqui: http: // fwhacking .blogspot.com / 2011/03 / bfsize-print-file-size-in-bytes-and.html
As duas formas mais limpas em minha opinião com ferramentas comuns do Linux são:
$ stat -c %s /usr/bin/stat
50000
$ wc -c < /usr/bin/wc
36912
Mas eu não quero ser parâmetros de digitação ou canalizar a saída apenas para obter um tamanho de arquivo, então eu estou usando minha própria bfsize.
Mesmo que du
normalmente imprime o uso do disco e não o tamanho de dados reais, GNU Coreutils du
pode imprimir "tamanho aparente" do arquivo em bytes:
du -b FILE
Mas não vai funcionar sob BSD, Solaris, MacOS, ...
Finalmente eu decidi usar ls, e expansão gama bash:
TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}
não é muito bom, mas pelo menos ele faz apenas 1 fork + execve, e não depende de linguagem de programação secundária (perl / ruby ??/ python / whatever)
Cross solução mais rápida plataforma (só usa garfo único () para ls , não tenta contar personagens reais, não desova awk desnecessários, perl, etc).
Testado em MacOS, Linux - pode exigir a modificação menor para Solaris:
__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"
Se necessário, simplificar a ls argumentos e ajustar deslocamento em $ {__ ln [3]}.
Nota:. Vai seguir os links
Se você usar find
de fileutils GNU:
size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )
Infelizmente, outras implementações de find
geralmente não suportam -maxdepth
, nem -printf
. Este é o caso de, por exemplo, Solaris e MacOS find
.
Quando o processamento de saída ls -n
, como uma alternativa para matrizes de shell mal-portáteis, você pode usar os argumentos posicionais, que formam a única variedade e são as variáveis ??única locais em shell padrão. Enrole a de substituição de argumentos posicionais em uma função de preservar os argumentos originais para o seu script ou função.
getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE
Isto divide a saída do ln -dn
de acordo com as configurações de ambiente IFS
variáveis ??atuais, atribui a argumentos posicionais e ecos o quinto. Os diretórios Garante -d
são tratadas adequadamente e os assegura -n
que os nomes de usuários e grupos não precisam ser resolvidos, ao contrário de -l
. Além disso, os nomes de utilizador e do grupo contendo espaços em branco podia teoricamente quebrar a estrutura esperada linha; eles são geralmente proibido, mas essa possibilidade ainda faz a parada programador e pensar.
Você pode usar o comando find
para obter algum conjunto de arquivos (aqui arquivos temporários são extraídos). Então você pode usar o comando du
para obter o tamanho de cada arquivo em formato legível com o interruptor -h
.
find $HOME -type f -name "*~" -exec du -h {} \;
SAÍDA:
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~
Você primeiro exemplo Perl não parece razoável para mim.
É por razões como esta que eu migraram de escrever scripts shell (em bash / sh etc.) para escrever todos, mas a maioria dos scripts triviais em Perl. Achei que eu estava tendo que lançar Perl para necessidades específicas, e como eu fiz isso mais e mais, eu percebi que escrever os scripts em Perl foi, provavelmente, um mais poderoso (em termos da linguagem e da grande variedade de bibliotecas disponíveis via < a href = "http://www.cpan.org" rel = "nofollow noreferrer"> CPAN ) e de maneira mais eficiente para conseguir o que eu queria.
Note que outras línguas shell-script (por exemplo python / rubi), sem dúvida, têm instalações semelhantes, e você pode querer avaliar estes para seus propósitos. Eu só discutir Perl já que é o uso da língua I e estou familiarizado com.
Se você tem Perl em seu Solaris, em seguida, usá-lo. Caso contrário, sl com awk é sua melhor opção, já que você não tem estatísticas ou seu achado não é GNU find.
Existe um truque no Solaris Eu tenho usado, se você perguntar para o tamanho de mais de um arquivo ele retorna apenas o tamanho total sem nomes - para incluir um arquivo vazio como / dev / null como o segundo arquivo:
eg comando fileyouwant / dev / null
Eu não posso rememebr qual comando tamanho Isso funciona para ls / wc / etc -. Infelizmente eu não tenho um solaris caixa para testá-lo
no linux você pode usar du -h $FILE
, é que isso funciona no Solaris também?
Você tentou du -ks | awk '{print $ 1 * 1024}'. Isso só poderia trabalhar.