Search code examples
shelldategnubsd

How can I detect BSD vs. GNU version of date in shell script


I am writing a shell script that needs to do some date string manipulation. The script should work across as many *nix variants as possible, so I need to handle situations where the machine might have the BSD or the GNU version of date.

What would be the most elegant way to test for the OS type, so I can send the correct date flags?

EDIT: To clarify, my goal is to use date's relative date calculation tools which seem distinct in BSD and GNU.

BSD example

date -v -1d

GNU example

date --date="1 day ago"

Solution

  • Use portable flags. The standard is available here

    For the particular problem of printing a relative date, it is probably easier to use perl than date:

    perl -E 'say scalar localtime(time - 86400)'
    

    (note that this solution utterly fails on 23 or 25 hour days, but many perl solutions are available to address that problem. See the perl faq.)

    but you could certainly use a variation of Keith's idea and do:

    if date -v -1d > /dev/null 2>&1; then
      DATE='date -v -1d'
    else
      DATE='date --date="1 day ago"'
    fi
    eval "$DATE"
    

    or just

    DATE=$(date -v -1d 2> /dev/null) || DATE=$(date --date="1 day ago")
    

    Another idea is to define a function to use:

    if date -v -1d > /dev/null 2>&1; then
        date1d() { date -v -1d; }
    else
        date1d() { date --date='1 day ago'; }
    fi