How to handle with problems with different commands on FreeBSD/Linux/macOS

Introduction
Due to the different commands between Linux (GNU coreutils) and FreeBSD, macOS, it is necessary to consider the environment in which the script is executed in the shell script. For example, if you want to get the last modified date and time of a file, you want stat to use it, but stat the flags that specify the output format are different between GNU coreutils, FreeBSD, and macOS.
I think it’s true that you can write in Perl or Python as a premise, but there are some things that you can’t do without shell scripts such as bash and zsh plugins. It’s a trivial matter if you just write it yourself and use it yourself, but it’s not so if it’s shared with others.
TL; DR
- Take advantage of syntax differences (stat)
- Substitute with a command with the same syntax (openssl)
Determine the environment by uname
There is a judgment by the most common coping method .
case "$(uname)"; in
Linux)
# GNU coreutils
;;
Darwin)
# macOS
;;
esac
This has one big problem: if you’re using GNU coreutils on macOS, the environment-based decision will fail in the first place. I’m using the shell script I use because I want to assume GNU coreutils. From the above, it is not so good to judge by the environment.
Take advantage of the difference in syntax
For example stat, the — help flag only exists in GNU coreutils, so it can be determined by the exit code when it is executed.
if stat --help >/dev/null 2>&1; then
modified_time_fmt="-c%y" # GNU coreutils
else
modified_time_fmt="-f%m" # FreeBSD, macOS
fistat $modified_date_fmt /path/to/file # It works!
This doesn’t depend on the environment, so it works well if you’re using GNU coreutils on macOS, but it’s best if you can use it without making a decision in the first place.
Substitute with a command that has the same syntax
I want to get md5. You md5sum can use it with GNU coreutils, but you md5 need to use this command on macOS and FreeBSD because it doesn’t exist .
You openssl can choose to use it in this case . openssl Is an OpenSSL command line utility, so there are differences depending on the version, but not on the environment.
$ openssl md5 test
MD5(test)= d41d8cd98f00b204e9800998ecf8427e
Since this method openssl assumes that is installed, the conditions that can be used are different from other methods, but it can be considered as an option.
Conclusion
Since shell scripts have problems due to differences in execution environment, it is better to keep them small even when using them.
by the author.