Search code examples
shellzsh

How to compare a string variable against a literal in zsh


I'm trying to do an OS check in my .zshrc. I can't get the string comparison against Ubuntu to match correctly when running on Ubuntu.

Snippet:

function get_linux_distro()
{
    echo `awk -F= '/^NAME/{print $2}' /etc/os-release`
}

function is_os_ubuntu()
{
    set -x
    local dist=`get_linux_distro`
    if [[ ${dist} = "Ubuntu"* ]]; then  # <<< string comp
        echo "UBUNTU"
        return 0
    else
        echo "BLAHHHH"
        return 1
    fi
}

Output:

❯ is_os_ubuntu
+is_os_ubuntu:4> get_linux_distro
+get_linux_distro:3> awk '-F=' '/^NAME/{print $2}' /etc/os-release
+get_linux_distro:3> echo '"Ubuntu"'
+is_os_ubuntu:4> local dist='"Ubuntu"'
+is_os_ubuntu:5> [[ '"Ubuntu"' = Ubuntu* ]]  # <<< don't match due to quotes??
+is_os_ubuntu:10> echo BLAHHHH
BLAHHHH
+is_os_ubuntu:11> return 1

Note: I've added the bash tag since I'm lead to believe this is the same in both and bash has more visibility.


Solution

  • How to correctly compare a string variable against a litteral in zsh

    Remove the * or quote it, otherwise, it's parsed as a glob expression. You are correctly comparing it.

    [[ ${dist} = "Ubuntu" ]]
    

    Because your string is not Ubuntu, but "Ubuntu", it's not equal and works correctly.

    Please do not ask XY questions.

    From man os-release:

    The basic file format of os-release is a newline-separated list of environment-like shell-compatible variable assignments. [...]

    Source the file in shell and output the variable, preferably in a subshell.

    get_linux_distro() {
        sh -c 'source /etc/os-release; echo "$NAME"'
    }
    

    Do not use backticks `. Prefer $(...).

    Do not use: echo $(something) - it's a useless use of echo, like echo $(echo $(echo $(something))). Just do the thing you want to do, without echo.

    Check your scripts with HTTP://shellcheck.net.