Portable way to get file size (in bytes) in shell?

2019-01-30 04:43发布

On Linux, I use stat --format="%s" FILE, but Solaris I have access to doesn't have stat command. What should I use then?

I'm writing Bash scripts, and can't really install any new software on the system.

I've considered already using:

perl -e '@x=stat(shift);print $x[7]' FILE

or even:

ls -nl FILE | awk '{print $5}'

But neither of these looks sensible - running Perl just to get file size? Or running 2 commands to do the same?

14条回答
Emotional °昔
2楼-- · 2019-01-30 05:04

You first Perl example doesn't look unreasonable to me.

It's for reasons like this that I migrated from writing shell scripts (in bash/sh etc.) to writing all but the most trivial scripts in Perl. I found that I was having to launch Perl for particular requirements, and as I did that more and more, I realised that writing the scripts in Perl was probably a more powerful (in terms of the language and the wide array of libraries available via CPAN) and more efficient way to achieve what I wanted.

Note that other shell-scripting languages (e.g. python/ruby) will no doubt have similar facilities, and you may want to evaluate these for your purposes. I only discuss Perl since that's the language I use and am familiar with.

查看更多
对你真心纯属浪费
3楼-- · 2019-01-30 05:04

Did you try du -ks | awk '{print $1*1024}'. That might just work.

查看更多
Lonely孤独者°
4楼-- · 2019-01-30 05:11

BSDs have stat with different options from the GNU coreutils one, but similar capabilities.

stat -f %z <file name> 

This works on macOS (tested on 10.12), FreeBSD, NetBSD and OpenBSD.

查看更多
Melony?
5楼-- · 2019-01-30 05:11

if you have Perl on your Solaris, then use it. Otherwise, ls with awk is your next best bet, since you don't have stat or your find is not GNU find.

查看更多
戒情不戒烟
6楼-- · 2019-01-30 05:12

When processing ls -n output, as an alternative to ill-portable shell arrays, you can use the positional arguments, which form the only array and are the only local variables in standard shell. Wrap the overwrite of positional arguments in a function to preserve the original arguments to your script or function.

getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE

This splits the output of ln -dn according to current IFS environment variable settings, assigns it to positional arguments and echoes the fifth one. The -d ensures directories are handled properly and the -n assures that user and group names do not need to be resolved, unlike with -l. Also, user and group names containing whitespace could theoretically break the expected line structure; they are usually disallowed, but this possibility still makes the programmer stop and think.

查看更多
三岁会撩人
7楼-- · 2019-01-30 05:13

There is a trick in Solaris I have used, if you ask for the size of more than one file it returns just the total size with no names - so include an empty file like /dev/null as the second file:

eg command fileyouwant /dev/null

I can't rememebr which size command this works for ls/wc/etc - unfortunately I don't have a solaris box to test it.

查看更多
登录 后发表回答