I was going to write the next installment in my New Features In Bash Version 4.x series today, but in thinking about the examples I want to use, I thought I should talk about the stat command first.
We're all familiar with ls. It's the first command that most people learn. Using ls you can get a lot of information about a file:
bshotts@twin7:~$ ls -l .bashrc
-rw-r--r-- 1 bshotts bshotts 3800 2010-03-25 13:18 .bashrc
Very handy. But there is one problem with ls; it's output is not very script friendly. Commands like cut cannot easily separate the fields (though awk can, but we're not talking about that yet). Wouldn't it be great if there was a command that let you get file information in a more flexible way?
Fortunately there is such a command. It's called stat. The name "stat" derives from the word status. The stat command shows the status of a file or file system. In it's basic form, it works like this:
bshotts@twin7:~$ stat .bashrc
Size: 3800 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 524890 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ bshotts) Gid: ( 1000/ bshotts)
Access: 2010-04-15 08:46:22.292601436 -0400
Modify: 2010-03-25 13:18:09.621972000 -0400
Change: 2010-03-27 08:41:31.024116233 -0400
As we can see, when given the name of a file (more than one may be specified), stat displays everything the system knows about the file short of examining its contents. We see the file name, its size including the number of blocks it's using and the size of the blocks used on the device. The attribute information includes the owner and group IDs, and the permission attributes in both symbolic and octal format. Finally we see the access (when the file was last read), modify (when the file was last written), and change (when the file attributes were last changed) times for the file.
Using the -f option, we can examine file systems as well:
bshotts@twin7:~$ stat -f /
ID: 9e38fe0b56e0096d Namelen: 255 Type: ext2/ext3
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 18429754 Free: 10441154 Available: 9504962
Inodes: Total: 4685824 Free: 4401092
Clearly stat delivers the goods when it comes to file information, but what about that output format? I can't think of anything worse to deal with from a script writer's point-of-view (actually I can, but let's not go there!).
Here's where the beauty of stat starts to shine through. The output is completely customizable. stat supports printf-like format specifiers. Here is an example extracting just the name, size, and octal file permissions:
bshotts@twin7:~$ stat -c "%n %s %a" .bashrc
.bashrc 3800 644
The -c option provides basic formatting capabilities, while the --printf option can do even more by interpreting backslash escape sequences:
bshotts@twin7:~$ stat --printf="%n\t%s\t%a\n" .bashrc
.bashrc 3800 644
Using this format, we can produce tab-delimited output, perfect for processing by the cut command. Each of the fields in the stat output is available for formatting. See the stat man page for the complete list.