在Linux上,我使用stat --format="%s" FILE,但我有权访问的Solaris没有stat命令.那我应该怎么用?
我正在编写Bash脚本,无法在系统上安装任何新软件.
我考虑过已经使用过:
perl -e '@x=stat(shift);print $x[7]' FILE
Run Code Online (Sandbox Code Playgroud)
甚至:
ls -nl FILE | awk '{print $5}'
Run Code Online (Sandbox Code Playgroud)
但这些看起来都不合理 - 运行Perl只是为了获得文件大小?或者运行2个命令来做同样的事情?
Car*_*icz 198
wc -c < filename(字数统计,-c打印字节数)是一种便携式POSIX解决方案.只有输出格式在不同平台上可能不一致,因为某些空格可能会被预先添加(Solaris就是这种情况).
不要省略输入重定向.当文件作为参数传递时,文件名将在字节计数后打印.
我担心它对二进制文件不起作用,但它在Linux和Solaris上都可以正常工作.你可以尝试一下wc -c < /usr/bin/wc.此外,POSIX实用程序保证处理二进制文件,除非另有明确说明.
小智 37
我最终编写了自己的程序(非常小)来显示大小.更多信息请访问:http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
在我看来,使用常见Linux工具的两种最干净的方法是:
$ stat -c %s /usr/bin/stat
50000
$ wc -c < /usr/bin/wc
36912
Run Code Online (Sandbox Code Playgroud)
但我只是不想输入参数或管道输出只是为了获得文件大小,所以我使用自己的bfsize.
小智 25
即使du通常打印磁盘使用而不是实际数据大小,GNU coreutils du也可以以字节为单位打印文件的"表观大小":
du -b FILE
Run Code Online (Sandbox Code Playgroud)
但它不适用于BSD,Solaris,macOS,......
小智 13
最后我决定使用ls和bash数组扩展:
TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}
Run Code Online (Sandbox Code Playgroud)
它不是很好,但至少它只有1个fork + execve,它不依赖于二级编程语言(perl/ruby/python/whatever)
跨平台最快的解决方案(仅对ls使用单fork(),不尝试计算实际字符,不产生不需要的awk,perl等).
在MacOS,Linux上测试 - 可能需要对Solaris进行少量修改:
__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"
Run Code Online (Sandbox Code Playgroud)
如果需要,简化ls参数,并调整$ {__ ln [3]}中的偏移量.
注意:将遵循符号链接.
小智 7
在处理ls -n输出时,作为不可移植的 shell 数组的替代方法,您可以使用位置参数,它形成唯一的数组,并且是标准 shell 中唯一的局部变量。在函数中包装位置参数的覆盖以保留脚本或函数的原始参数。
getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE
Run Code Online (Sandbox Code Playgroud)
这会ln -dn根据当前IFS环境变量设置拆分 的输出,将其分配给位置参数并回显第五个。在-d确保目录得到妥善处理和-n用户名和组名不需要保证得到解决,不像-l。此外,包含空格的用户名和组名理论上可能会破坏预期的行结构;它们通常是不允许的,但这种可能性仍然让程序员停下来思考。
如果您find从 GNU fileutils使用:
size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )
Run Code Online (Sandbox Code Playgroud)
不幸的是, 的其他实现find通常不支持-maxdepth,也不支持-printf。例如 Solaris 和 macOS 就是这种情况find。