9

I use several different OS's at home and work and I want to be able to load platorm-specific ZSH settings conditionally, depending on which OS I'm using at the given moment.

I tried this but it doesn't load everything I expect:

# Condtitional loading of zsh settings per platform

if command apt > /dev/null; then
    source $ZSH_CUSTOM/os/debian.zsh

elif command systemctl > /dev/null; then
    source $ZSH_CUSTOM/os/systemd.zsh

elif command freebsd-version > /dev/null; then
    source $ZSH_CUSTOM/os/freebsd.zsh

elif [[ `uname` == "Darwin" ]]; then
    source $ZSH_CUSTOM/os/mac.zsh

elif command kubectl > /dev/null; then
    source $ZSH_CUSTOM/os/kubernetes.zsh

else
    echo 'Unknown OS!'
fi

What is the best way to do this detection and what I'm doing wrong? I know this approach of mine doesn't work as when I run zsh -o SOURCE_TRACE, it doesn't show all desired files sourced.

Thanks in advance!

dzhi
  • 1,534
  • 2
  • 18
  • 29
  • Presumably `/etc` is unique to each OS; just add an environment variable to `/etc/zshenv` that identifies the current OS, and check that variable in your configuration. – chepner Feb 09 '19 at 15:27
  • @chepner which part of /etc you'd target? – dzhi Feb 09 '19 at 15:29
  • `/etc/zshenv`. A lot of what's in `/etc` is OS-specific (or at least distribution-specific), so I'm assuming you aren't sharing the same directory between OS installs. – chepner Feb 09 '19 at 17:38
  • Possible duplicate of [How to detect the OS from a Bash script?](https://stackoverflow.com/q/394230/608639) – jww Feb 09 '19 at 18:12

2 Answers2

8

Revised Answer (2020-Feb-09)

Thanks to @Cyberbeni for reminding me that apt on macOS would incorrectly match the system Java runtime's Annotation Processing Tool. Rolling up the necessary changes, we now have:

# What OS are we running?
if [[ $(uname) == "Darwin" ]]; then
    source "$ZSH_CUSTOM"/os/mac.zsh

elif command -v freebsd-version > /dev/null; then
    source "$ZSH_CUSTOM"/os/freebsd.zsh

elif command -v apt > /dev/null; then
    source "$ZSH_CUSTOM"/os/debian.zsh

else
    echo 'Unknown OS!'
fi

# Do we have systemd on board?
if command -v systemctl > /dev/null; then
    source "$ZSH_CUSTOM"/os/systemd.zsh
fi

# Ditto Kubernetes?
if command -v kubectl > /dev/null; then
    source "$ZSH_CUSTOM"/os/kubernetes.zsh
fi

Original answer

I answered exactly the same question on Reddit here, so to close the loop, here's what I wrote:

Your current logic literally says that, for instance, a Debian system cannot possibly run systemd or Kubernetes, which is clearly untrue. That's exactly what if...elif...else...fi implements: mutual exclusivity.

It looks to me like only the OS-specific tests need to be mutually exclusive, so you're probably looking at something like:

# What OS are we running?
if command apt > /dev/null; then
    source $ZSH_CUSTOM/os/debian.zsh

elif command freebsd-version > /dev/null; then
    source $ZSH_CUSTOM/os/freebsd.zsh

elif [[ `uname` == "Darwin" ]]; then
    source $ZSH_CUSTOM/os/mac.zsh

else
    echo 'Unknown OS!'
fi

# Do we have systemd on board?
if command systemctl > /dev/null; then
    source $ZSH_CUSTOM/os/systemd.zsh
fi

# Ditto Kubernetes?
if command kubectl > /dev/null; then
    source $ZSH_CUSTOM/os/kubernetes.zsh
fi

UPDATE: Actually, I didn't look closely enough at your code, and you're also calling command wrong. All your invocations should be of the form:

if command -v <cmd_name> > /dev/null

which returns success if <cmd_name> is found in your PATH. command <cmd_name> actually runs <cmd_name> and returns its exit status, which can return a failure exit code (i.e. false negative) due to lack of appropriate arguments.

Adrian
  • 595
  • 4
  • 9
  • 1
    macOS 13.1 also has apt preinstalled (although when you try to run `apt --help` or similar, it just complains that there is no Java Runtime) – Cyberbeni Jan 18 '23 at 11:40
0

Verifying an OS is system dependent. You can use the package managers to verify a certain distribution, but this not desired, since there are certainly other distributions which the same package manager as well.

You can try to use lsb_release and grep on the correct distribution. Or use uname.

Which OS'es do not load in your script, and which do?

Also, take a look here

Kevin C
  • 4,851
  • 8
  • 30
  • 64