Reputation: 3290
This seems to be a classic case of non-standard features on various platforms.
Quite simply, I want a universally (or at least widely) supported method for getting the modified time of a file as a unix timestamp in seconds.
Now I know of various ways to do this with stat
but most are platform specific; for example stat -c %Y $file
works for some, but won't work on OS X (and presumably other FreeBSD systems) which uses stat -f %m $file
instead.
Likewise, some platforms support date -r $file +%s
, however OS X/FreeBSD again does not as the -r
option seems to just be an alternate to using +%s
for getting a unix timestamp, rather than the reference file option as on other platforms.
The other alternative I'm familiar with is to use find
with the -printf
option, but again this is not widely supported. The last method I know of is parsing ls
which, aside from being an unpleasant thing to have to do, is not something I believe can (or at least should) be relied upon either.
So, is there a more compatible method for getting a file's modified time? Currently I'm just throwing different variations of stat
into a script and running them until one exits with a status of zero, but this is far from ideal, even if I cache the successful command to run first in future.
Upvotes: 9
Views: 5442
Reputation: 3290
Since it seems like there might not be a "correct" solution I figured I'd post my current one for comparison:
if stat -c %Y . >/dev/null 2>&1; then
get_modified_time() { stat -c %Y "$1" 2>/dev/null; }
elif stat -f %m . >/dev/null 2>&1; then
get_modified_time() { stat -f %m "$1" 2>/dev/null; }
elif date -r . +%s >/dev/null 2>&1; then
get_modified_time() { date -r "$1" +%s 2>/dev/null; }
else
echo 'get_modified_time() is unsupported' >&2
get_modified_time() { printf '%s' 0; }
fi
[edit]
I'm updating this to reflect the more up to date version of the code I use, basically it tests the two main stat
methods and a somewhat common date
method in any attempt to get the modified time for the current working directory, and if one of the methods succeeds it creates a function encapsulating it for use later in the script.
This method differs from the previous one I posted since it always does some processing, even if get_modified_time
is never called, but it's more efficiently overall if you do need to call it most of the time. It also lets you catch an unsupported platform earlier on.
If you prefer the function that only tests functions when it is called, then here's the other form:
get_modified_time() {
modified_time=$(stat -c %Y "$1" 2> /dev/null)
if [ "$?" -ne 0 ]; then
modified_time=$(stat -f %m "$1" 2> /dev/null)
if [ "$?" -ne 0 ]; then
modified_time=$(date -r "$1" +%s 2> /dev/null)
[ "$?" -ne 0 ] && modified_time=0
fi
fi
echo "$modified_time"
}
Upvotes: 8
Reputation: 11
Why so complicated?
after not finding something on the web I simply read the manual of ls
man ls
which gave me
ls --time-style=full-iso -l
and change time in the format hh:mm:ss.sssssssss
As
ls --time-style=+FORMAT -l
while FORMAT
is used like with date (see man date
)
ls --time-style=+%c
will give you local date and time with seconds as an integer (without decimal point).
You can strip off additional ls information (e.g. file name, owner...) when you pipe through awk
.
Upvotes: 1
Reputation: 249394
Just ask the operating system for its name, and go from there. Alternatively, write a C program, or use Python or something else that's pretty common and more standardized: How to get file creation & modification date/times in Python?
Upvotes: 0