# Geek # # Linux # # FreeBSD # # bash # # *NIX #

Porting wygibtwys bash script from Linux to FreeBSD

I recently ported my wygibtwys website generator bash script from Linux to FreeBSD, as it is a requirement for me to migrate my devbox to FreeBSD
All in all it was a quite straight but interesting process - as I wanted to keep Linux compatibility, this post will highlight the changes.

Shebang

Changing the shebang each time you change system is not complicated, but not very handy. Changing it to:


#!/usr/bin/env bash

allowed the script to run indifferently on Debian and FreeBSD - though it might not be the most elegant solution.


Finding corresponding packages

Most packages I needed where available directly with apt/pkg - with the exception of tidy on debian and linkchecker on FreeBSD. While some of those packages are the same on both systems, sometimes they don't take the same arguments (BSD vs GNU tools...) - some also use different paths.


OS detection

Detecting the OS allows to change some lines on the run. The first try looked like something like:


ssystem=$(uname)

And each time the command would change, I would insert a line that looked like


if [[ "$ssystem" = "Linux" ]]; then dothis; elif [[ "$ssystem" = "FreeBSD" ]]; then dothat; fi

I did not like to have those ifs everywhere, so I placed one if at the beginning and loaded the differences in variables.
This led to an issue with sed, which was solved with eval


ssystem=$(uname)
if [[ "$ssystem" = "FreeBSD" ]]; then
  cccleaner="/usr/local/bin/tidy5"
  sssed='sed -i ""'
  tttac="tail -r"
  lllinkch="linkchecker --no-status"
  function f_keepsmallest {
    if [[ "$(stat -f %z "$1")" -le "$(stat -f %z "$2")" ]]; then rm "$2" && return 0;else return 1;fi
  }
elif [[ "$ssystem" = "Linux" ]]; then
  cccleaner="/usr/local/bin/tidy"
  sssed="sed -i"
  tttac="tac"
  lllinkch="linkchecker --no-status --check-html --check-css"
  function f_keepsmallest {
    if [[ "$(stat --printf="%s" "$1")" -le "$(stat --printf="%s" "$2")" ]]; then rm "$2" && return 0;else return 1;fi
  }
fi

Conclusion

As mentioned, the changes where quite straigtforward and I was happy to be able to group all differences between systems at the same place, as it separates it from the program logic. I believe that shellcheck made my easier to port, as it helped iron out "fragile" points.
I guess working on my backups might be one of the next steps!

Let this post be a source of inspiration to making more portable scripts!



view_list Categories