17th October 2018
One of the first tools that a newcomer to Unix or Linux learns is the ls
command. It lists files; by default,
it lists all of the files (apart from those which begin with a period, such as .bash_profile
) in the current directory. And
it formats them in convenient columns, organised to match the size of your terminal window:
steve@linux:/tmp/eg$ ls 17abc path.xcf tree.xcf burton-colour.odp profile.xfg walks git.txt redstar.sun wargames.jpg logo.xcf
The second thing people learn about ls
is that you can use ls -l
to give a long listing. This shows the owner, file type, and timestamp (which
is normally the modification time). And then the third thing is that ls -ltr
orders them by that timestamp. The -r
reverses the order, so that older files are listed at the top, with the newest file at the bottom.
What people often only casually notice, however, is that ls
has two different ways of displaying the timestamp of a file:
steve@linux:/tmp/eg$ ls -ltr drwxr-xr-x 2 steve steve 4096 Jul 10 2016 walks drwxr-xr-x 11 steve steve 4096 Mar 3 2018 17abc drwxr-xr-x 3 steve steve 4096 Sep 27 23:14 tmp -rw-r--r-- 1 steve steve 361402 Oct 17 21:39 wargames.jpg . . .
The first two files (which happen to be directories, but in *nix, everything is a file) are in the format "Month Day Year", but the other two are in the format "Month Day Time." The older a file is, the less relevant its actual time of modification becomes. And it saves a little bit of space to choose one format or the other. But what many people assume is that this changeover happens when a file is more than a year old.
But that wouldn't really work too well. If today was the 1st of January, then pretty much every file you listed would be in the "Month Day Year" format, and you wouldn't see the hours and minutes even on a file you edited yesterday. That would be pretty annoying.
If it was anything over 12 months old, then files around today's date would start to look a bit confusing. So GNU's ls
, at least, uses a cut-off date of 6 months ago.
From info '(coreutils) ls invocation'
:
A timestamp is considered to be "recent" if it is less than six months old, and is not dated in the future.
This is demonstrated in the listing above; this article was written on 17th October 2018, so the two newest files are less than six months old. They are shown with the actual modification
time. But the "17abc
" directory is from March 2018, so it is just over 7 months old. It is listed in the same format as the 2016 "walks
" directory.
Parsing the output from ls
is a really bad idea; even when you're doing it by eye. Doing it in a shell script is totally unnecessary, when you have the stat
command at your fingertips.
steve@linux:/tmp/eg$ stat 17abc File: ‘17abc’ Size: 4096 Blocks: 8 IO Block: 4096 directory Device: fd05h/64773d Inode: 651553 Links: 11 Access: (0755/drwxr-xr-x) Uid: ( 1000/ steve) Gid: ( 1000/ steve) Access: 2018-03-03 07:34:00.000000000 +0000 Modify: 2018-03-03 07:34:00.000000000 +0000 Change: 2018-10-17 21:51:15.213895227 +0100 Birth: - steve@linux:/tmp/eg$
This shows you in a much more detailed and accessible format the metadata about the file. However, there is an even better way. stat -c
takes formatting
strings which allow you to select specific pieces of data about the file.
The %y
formatting string selects the modification time.
steve@linux:/tmp/eg$ stat -c %y 17abc 2018-03-03 07:34:00.000000000 +0000 steve@linux:/tmp/eg$
The %A %U %n
formatting string selects the access permissions, the owner's name, and the file's name.
steve@linux:/tmp/eg$ stat -c "%A %U %n" 17abc drwxr-xr-x steve 17abc steve@linux:/tmp/eg$
See man stat
for the full list of formatting strings. You can derive a lot of information from a file, and you can also (like printf
and other tools)
include your own text in the output:
steve@linux:/tmp/eg$ stat -c "The file %n has %A permissions and is owned by %U (UID %u)" 17abc The file 17abc has drwxr-xr-x permissions and is owned by steve (UID 1000) steve@linux:/tmp/eg$
You can (and should) use the stat
command in your shell scripts whenever you need to get metadata about a file. It is a much easier way than parsing the output
of ls
or other such utilities. stat
gives you a tremendous amount of flexibility.
However, it is not available in all Unix variants, although every GNU/Linux system should have it included, as is is part of the GNU 'coreutils' package.
My Shell Scripting books, available in Paperback and eBook formats. This tutorial is more of a general introduction to Shell Scripting, the longer Shell Scripting: Expert Recipes for Linux, Bash and more book covers every aspect of Bash in detail.
![]() Shell Scripting Tutorial is this tutorial, in 88-page Paperback and eBook formats. Convenient to read on the go, and in paperback format good to keep by your desk as an ever-present companion. Also available in PDF form from Gumroad:Get this tutorial as a PDF | ![]() Shell Scripting: Expert Recipes for Linux, Bash and more is my 564-page book on Shell Scripting. The first half covers all of the features of the shell in every detail; the second half has real-world shell scripts, organised by topic, along with detailed discussion of each script. |