skip to Main Content

This seems like a basic thing yet I can’t get it work properly. I have a bash script where I want to compare the OS version (11 or 12 in Debian’s case) and do something depending on the version. Here is what I have:

if [ cat /etc/*release | sed -n '3p' | cut -c 13-14 == '12' ]
then
   perform actions 

The command above works on the command line on Debian 11 (without the comparison) and prints out either 11 or 12. However, running it on Debian 12 says it is Debian 11. Does anyone know what I am doing wrong?

2

Answers


  1. Does anyone know what I am doing wrong?

    For starters, a UUoC. Why cat file|sed? Just sed -n '3p' /etc/*release. I’d also skip the extraneous cut. On my Centos: sed -n '/^VERSION=/{s/[^0-9]//g;p}' /etc/*release gives me 7. Likewise, if you are using bash you should almost always use [[...]] instead of [...], for several reasons, though there are arguments on either side – just know the syntax for whichever you are using.

    The real problem here, though, is that you need a $(...) subshell, or at least backticks.

    $: if [ cat /etc/*release | sed -n '3p' | cut -c 13-14 == '12' ] ; then echo ok; else echo no; fi
    -bash: [: missing `]'
    cut: ==: No such file or directory
    cut: 12: No such file or directory
    cut: ]: No such file or directory
    no
    
    $: if [[ `cat /etc/*release | sed -n '3p' | cut -c 13-14` == '12' ]] ; then echo ok; else echo no; fi
    no
    
    $: if grep -q '^VERSION_ID="7"' /etc/*release; then echo ok; else echo no; fi
    ok
    
    $: if [[ 7 == $(sed -n $'/^VERSION_ID=/!dns/[^0-9]//g' /etc/*release) ]] ; then echo ok; else echo no; fi
    ok
    
    $: if [[ 7 == $(awk '/^VERSION_ID=/{print gensub(/[^0-9]/,"","g")}' /etc/*release) ]] ; then echo ok; else echo no; fi
    ok
    

    I recommend the first one, the grep with no brackets at all, which is doing exactly what you want without embedding it into some other syntax. (Obviously you’d want to change the 7 to a 12, or some appropriate pattern, but I recommend keeping the quotes.)

    When something isn’t working, paste your code at ShellCheck. It will often help.

     
    Line 1:
    if [ cat /etc/*release | sed -n '3p' | cut -c 13-14 == '12' ]
    ^-- SC1009 (info): The mentioned syntax error was in this if expression.
       ^-- SC1073 (error): Couldn't parse this test expression. Fix to allow more checks.
         ^-- SC1014 (warning): Use 'if cmd; then ..' to check exit code, or 'if [[ $(cmd) == .. ]]' to check output.
             ^-- SC1072 (error): Expected test to end here (don't wrap commands in []/[[]]). Fix any mentioned problems and try again.
             ^-- SC1076 (error): Trying to do math? Use e.g. [ $((i/2+7)) -ge 18 ].
    

    You should also confirm that the record you want looks like the pattern I’m checking in Debian. You’re apparently looking at VERSION_ID (I was checking VERSION) so I updated that.

    Login or Signup to reply.
  2. #!/bin/bash
    
    # first approach getting version from /etc/os-release
    version=$(awk -F'"' '/^VERSION_ID=/{print $2}' /etc/os-release)
    echo "$version"
    if [ "$version" -eq 12 ]; then echo true; else echo false; fi
    
    # second approach getting version from /etc/debian_version
    version=$(</etc/debian_version)
    echo "$version"
    if [[ "$version" =~ ^12. ]]; then echo true; else echo false; fi
    

    output:

    12
    true
    12.0
    true
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search