'size' vs 'ls -l' to get the size of an executable file - linux

For the same file, I think the output of ls -l xxx is always greater than or equal to the output of size xxx.
But when I type ls -l /bin/ls the output is:
-rwxr-xr-x 1 root root 104508 1月 14 2015 /bin/ls
For size /bin/ls, the output is:
text data bss dec hex filename
101298 976 3104 105378 19ba2 /bin/ls
Why is ls showing less than size? 104508 < 105378

ls -l is telling you the size of the file, while the size command tells you the size of the executable image stored in the file -- how much memory it will require when loaded. Some segments (such as .bss) are zero-initialized rather than requiring data in the file to initialize them, so the the file may well be smaller than the executable image as a result.

Related

file created through 'truncate -s' can not get expected size

I create a file using truncate -s 1024M a.test.
I was expecting a file size of a.test to be 1024M, but not getting correct size somehow.
Below is my code.
$du -sh a.test
4.0K a.test
When using ls -l a.test, it is ok:
$ ll a.test
-rw-rw-r-- 1 work work 1073741824 Jul 12 17:26 a.test
Can some one help me out with this issue.
du tells you how much actual disk space you use. Since your file does not have any data in it, the OS will store it as a sparse file, so actual disk usage is much smaller than the size of the file. If you check it with "du --apparent-size -sh a.test", then that will report what you expected.

Backup log files in tomcat server by shell script with gzip command

I have some logs file that were created in the tomcat application, I backup the files by shell script that performs contraction by gzip command, after contraction, although that already the old log files do not exist, they are still taking up memory and space in disk,
This depletes the resources of the disc!
This is the code of shell script:
mkdir /tmp/backUp
mv `find $TOMCATDIR/logs/*.log -mtime +3` /tmp/backUp
cd /tmp/backUp
gzip *
after the script is run, the files still exist in the disk(although they aren't open)
lsof |grep "deleted"
java 584 cg 9w REG 253,7 2253 18317840 /app/jakarta/apache-tomcat-8.0.9_xxx/logs/back06.07/catalina.06-02.log (deleted)
java 584 cg 10w REG 253, 7 881 18317446 /app/jakartaapache-tomcat-8.0.9_xxx/logs/back06.07/localhost.06-02.log (deleted)
.......
....
...
Files are deleted from filesystem where is deleted any reference to this inode. Reference can be on disk (link in any directory), and.. from open applications. If you remove file - you only delete reference from disk, but - there is still reference from application.
You can "free" space in two ways then:
you can kill application which opened file.
you can truncate file.
If you know pid - look what files are open by this pid: ls -l /proc/PID/fd you see here links like:
undefine#uml:~$ ls -l /proc/18596/fd
razem 0
lrwx------ 1 undefine undefine 64 lut 1 00:06 0 -> /dev/pts/30
lrwx------ 1 undefine undefine 64 lut 1 00:06 1 -> /dev/pts/30
lrwx------ 1 undefine undefine 64 lut 1 00:05 2 -> /dev/pts/30
lr-x------ 1 undefine undefine 64 lut 1 00:06 3 -> /home/undefine/x (deleted)
lr-x------ 1 undefine undefine 64 lut 1 00:06 4 -> anon_inode:inotify
As you see - 3 fd is deleted. you can truncate it by command (for example):
undefine#uml:~$ :>/proc/18596/fd/3
undefine#uml:~$
Remember that if application read from this file - it can be dangerous to them. But - if it's only a log file - you can truncate it safetly.

How does `ls -lh` round file size?

I'm comparing the rounded file size value displayed by ls -lh to the raw size in bytes (as displayed by ls -l, say). I'm having a hard time figuring out what algorithm it uses to do the conversion from bytes.
My assumption is that it interprets the units K,M,G as either
(a) 10^3, 10^6, 10^9, or
(b) 1024, 1024^2, 1024^3.
On the one hand, I have one file that ls -l reports as 2052 bytes, and ls -lh rounds to 2.1K:
$ ls -l usercount.c
-rw-r--r-- 1 squirrel lsf 2052 May 13 15:41 usercount.c
$ ls -lh usercount.c
-rw-r--r-- 1 squirrel lsf 2.1K May 13 15:41 usercount.c
This would seem to support hypothesis (a), because 2052/1000=2.052 which rounds up to 2.1K but 2052/1024=2.0039 which clearly would display as 2.0K when rounded to one decimal place.
On the other hand, I have another file that ls -l reports as being 7223 bytes, which ls -lh displays as 7.1K:
$ ls -l traverse.readdir_r.c
-rw-r--r-- 1 squirrel lsf 7223 Jul 21 2014 traverse.readdir_r.c
$ ls -lh traverse.readdir_r.c
-rw-r--r-- 1 squirrel lsf 7.1K Jul 21 2014 traverse.readdir_r.c
This confusingly supports hypthesis (b), because 7223/1000=7.223 which should round down to 7.2K, but 7223/1024=7.0537 which rounds up to the displayed 7.1K
This leads me to conclude that my assumption is wrong and that it does neither (a) nor (b) exclusively. What algorithm does ls use to do this rounding?
GNU ls will by default round up in 1024-based units.
It does not round to nearest, as you've taken for granted.
Here's the formatting flag from gnulib human.h:
/* Round to plus infinity (default). */
human_ceiling = 0,
This is consistent with everything you're seeing:
2052 is 2.0039 KiB which rounds up to 2.1
7223 is 7.0537 KiB which rounds up to 7.1
by default the block size in ls is 1024, but for example if the output is 44.203125k it will round it to 45k
you can change it too
ls -lh --block-size=1000
and the source code: ls source code

How to edit FreeBSD .gz bootfile?

I have virtual image of a FreeBSD system and when I mount it I don't see the /etc/ directory and other files, instead is a big loader.gz on the filesystem, that I believe that is extracted during the boot process. I decompressed the loader.gz with gzip and I got it:
$ file loader
loader: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), not stripped
Using grep I'm able to confirm that the files that I need to edit are inside, however I don't know how to edit it. I tried to mount it without success. How can I modify the contents of loader.gz and use it again?
Can you please give me an example?
I have a Linux system and a Mac to install tools and this FreeBSD image.
Please, help me.
The loader program is generally the last stage of the kernel bootstrapping process.
A recent image should have another signature. e.g. for a memory stick image;
> file tmp/FreeBSD-10.0-RELEASE-amd64-memstick.img
tmp/FreeBSD-10.0-RELEASE-amd64-memstick.img: Unix Fast File system
[v1] (little-endian), last mounted on ,
last written at Fri Jan 17 00:24:02 2014,
clean flag 1, number of blocks 681040, number of data blocks 679047,
number of cylinder groups 13, block size 8192, fragment size 1024,
minimum percentage of free blocks 8, rotational delay 0ms,
disk rotational speed 60rps, TIME optimization
Mounting an image on FreeBSD:
# mdconfig -a -t vnode -f tmp/FreeBSD-10.0-RELEASE-amd64-memstick.img -u 1
# mount /dev/md1a /mnt/root/
(Linux has the same capability, I just don't remember what its called.)
This image contains loader in the boot/ directory:
# ls /mnt/root/
.cshrc ERRATA.TXT README.TXT boot/ lib/ proc/ sys#
.profile HARDWARE.HTM RELNOTES.HTM dev/ libexec/ rescue/ tmp/
COPYRIGHT HARDWARE.TXT RELNOTES.TXT docbook.css media/ root/ usr/
ERRATA.HTM README.HTM bin/ etc/ mnt/ sbin/ var/
# ls /mnt/root/boot/
beastie.4th check-password.4th gptzfsboot menu.4th support.4th
boot color.4th kernel/ menu.rc userboot.so
boot0 defaults/ loader* menusets.4th version.4th
boot0sio delay.4th loader.4th modules/ zfs/
boot1 device.hints loader.help pmbr zfsboot
boot2 firmware/ loader.rc pxeboot zfsloader*
brand.4th frames.4th mbr screen.4th
cdboot gptboot menu-commands.4th shortcuts.4th
On my FreeBSD 10 system, loader has another signature;
/boot/loader: FreeBSD/i386 demand paged executable

Size() vs ls -la vs du -h which one is correct size?

I was compiling a custom kernel, and I wanted to test the size of the image file.
These are the results:
ls -la | grep vmlinux
-rwxr-xr-x 1 root root 8167158 May 21 12:14 vmlinux
du -h vmlinux
3.8M vmlinux
size vmlinux
text data bss dec hex filename
2221248 676148 544768 3442164 3485f4 vmlinux
Since all of them show different sizes, which one is closest to the actual image size?
Why are they different?
They are all correct, they just show different sizes.
ls shows size of the file (when you open and read it, that's how many bytes you will get)
du shows actual disk usage which can be smaller than the file size due to holes
size shows the size of the runtime image of an object/executable which is not directly related to the size of the file (bss uses no bytes in the file no matter how large, the file may contain debugging information that is not part of the runtime image, etc.)
If you want to know how much RAM/ROM an executable will take excluding dynamic memory allocation, size gives you the information you need.
Two definition need to be understood
1 runtime vs storetime (this is why size differs)
2 file depth vs directory (this is why du differs)
Look at the below example:
[root#localhost test]# ls -l
total 36
-rw-r--r-- 1 root root 712 May 12 19:50 a.c
-rw-r--r-- 1 root root 3561 May 12 19:42 a.h
-rwxr-xr-x 1 root root 71624 May 12 19:50 a.out
-rw-r--r-- 1 root root 1403 May 8 00:15 b.c
-rw-r--r-- 1 root root 1403 May 8 00:15 c.c
[root#localhost test]# du -abch --max-depth=1
1.4K ./b.c
1.4K ./c.c
3.5K ./a.h
712 ./a.c
70K ./a.out
81K .
81K total
[root#localhost test]# ls -l
total 36
-rw-r--r-- 1 root root 712 May 12 19:50 a.c
-rw-r--r-- 1 root root 3561 May 12 19:42 a.h
-rwxr-xr-x 1 root root 71624 May 12 19:50 a.out
-rw-r--r-- 1 root root 1403 May 8 00:15 b.c
-rw-r--r-- 1 root root 1403 May 8 00:15 c.c
[root#localhost test]# size a.out
text data bss dec hex filename
3655 640 16 4311 10d7 a.out
If using size not on executable, OS will report an error.
Empirically differences happen most often for sparse files and for compressed files and can go in both directions.
du < ls
Sparse files contain metadata about space needed for an application, which ls reads and applies for its result, while du doesn't. For example:
truncate -s 1m test.dat
creates a sparse file consisting entirely of nulls without disk usage, ie. du shows 0 and ls shows 1M.
du > ls
On the other hand du can indicate, as in your case, files which might occupy a lot of space on disk (ie. they spread among lots of blocks), but not all blocks are filled, i.e. their bytesize (measured by ls) is smaller than du (looking at occupied blocks). I observed this rather prominently e.g. for some python pickle files.

Resources