Solved GNU date to *BSD date conversion issues

Currently I am converting all my Linux scripts to FreeBSD, which is reeeeaaaaally time consuming. Maybe a stupid question, but is there a script which can do it automatically?

But my current problem is to convert the date command.

I had a useful counter function in my .zsh_aliases, which could convert seconds in a time format, so if I put in 65 seconds as an argument the timer showed 00:01:05.

Here is the Linux version:
Code:
function countdown()
{
    date1=$((`date +%s` + $1));
    while [ "$date1" -ge `date +%s` ]; do
      echo -ne "$(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r";
      sleep 0.1
    done
}

After reading that the --date flag isn't available and one should use the -v flag, I tried the following:
Code:
function countdown()
{
   date1=$((`date +%s`+$1));
   while [ "$date1" -ge `date +%s` ]; do
     echo -ne "$(date -v$(($date1 - `date +%s`))S +%H:%M:%S)\r";
     sleep 0.1
   done
}

But it shows me a weird hour and minute and if the seconds are larger than 59 seconds, it doesn't work anymore.

If this is fixable I would be very thankful, but I am open to completely other ways of having a countdown in the terminal (showing HH:MM:SS).

Thanks a lot for your help.
 
Use -r instead:
Bash:
#!/bin/sh

date1=$((`date +%s`+$1));
while [ "$date1" -ge `date +%s` ]; do
        printf "$(date -ur $(($date1 - `date +%s`)) +%H:%M:%S)\r"
        sleep 0.1
done
 
Works like a charme now. Thanks a lot

Is there something like a comparison table to look up the equivalent from GNU to *BSD? Or is there even something like a script which is able to convert GNU to *BSD stuff? Just asking, because I have a lot of scripts I used with Linux and if it takes days or even weeks to rewrite them, I don't know if it's worth it to switch to FreeBSD. How do people solve this problem?

I am thankful for any tip.
 
By the way, zsh has quite a few time-related features built-in. So, in many cases you don't need to use the operating system's date(1) or other programs, so your zsh code is OS-independent and will work with Linux and BSD without changes. I even use zsh on Windows (in a cygwin environment), and my .zshrc works there as well.

For example, instead of date +%s you can write print -P "%D{%s}" in zsh. Another advantage: It is more efficient because no external program needs to be executed.

For more sophisticated date and time operations, the zsh/datetime module is provided. Read about it in the zshmodules(1) manual page. Using it is simple – This is how I would do it:
Code:
zmodload zsh/datetime      # need to do this only once

function countdown ()
{
        local REMAINDER=$1
        local TARGET=$(( EPOCHSECONDS + REMAINDER ))
        while (( REMAINDER >= 0 )); do
                printf '%s\r' $(TZ=UTC strftime '%T' $REMAINDER)
                sleep 0.1
                REMAINDER=$(( TARGET - EPOCHSECONDS ))
        done
}
 
You can actually install GNU date if necessary, it is part of sysutils/coreutils.

Under FreeBSD it is run a gdate()

wow... thanks a lot. This makes a lot of stuff much easier and saves time. This will be currently my ducktaped solution, because in another thread people recommend to rewrite it to a POSIX version and make case blocks for *BSD and Linux.

By the way, zsh has quite a few time-related features built-in. So, in many cases you don't need to use the operating system's date(1) or other programs, so your zsh code is OS-independent and will work with Linux and BSD without changes. I even use zsh on Windows (in a cygwin environment), and my .zshrc works there as well.

For example, instead of date +%s you can write print -P "%D{%s}" in zsh. Another advantage: It is more efficient because no external program needs to be executed.

For more sophisticated date and time operations, the zsh/datetime module is provided. Read about it in the zshmodules(1) manual page. Using it is simple – This is how I would do it:
Code:
zmodload zsh/datetime      # need to do this only once

function countdown ()
{
        local REMAINDER=$1
        local TARGET=$(( EPOCHSECONDS + REMAINDER ))
        while (( REMAINDER >= 0 )); do
                printf '%s\r' $(TZ=UTC strftime '%T' $REMAINDER)
                sleep 0.1
                REMAINDER=$(( TARGET - EPOCHSECONDS ))
        done
}

I use zsh too, but all the zsh specific stuff will not work anymore if I publish my scripts and someone uses something else than zsh, right?

What do you guys think about using something which works on every platform the same, like Python or would you even recommend a completely other language?
 
I use zsh too, but all the zsh specific stuff will not work anymore if I publish my scripts and someone uses something else than zsh, right?
Well, I assumed it was only things for your personal use from within your ~/.zshrc.

If you intend to publish things, well, yes, then you are correct. In order to be able to run zsh scripts, people will have to install zsh. But that's not really a difficult thing either.
What do you guys think about using something which works on every platform the same, like Python or would you even recommend a completely other language?
That's probably not a bad idea. I like Python and I use it a lot myself.

Shell scripts are only useful for typical “batch processing” and for automating simple tasks, although modern shells like zsh have gained a lot of features known from high-level programming languages. However, as soon as a task exceeds a certain complexity, it's better to use a real programming language that supports larger projects. Python is a good example.

However, be aware that – if you publish such software – there are similar prerequisites as when publishing zsh scripts. That is, you'll have to advise people to install Python. Chances are that it is already installed, though, because many common software packages depend on Python anyway (directly or through other dependencies). For example, Python gets installed when you install Xorg, so basically every desktop PC has Python.
 
Back
Top