How to build a conditional assignment in bash?

后端 未结 8 2022
慢半拍i
慢半拍i 2021-01-31 01:04

I\'m looking a way to build conditional assignments in bash:

In Java it looks like this:

int variable= (condition) ? 1 : 0;
相关标签:
8条回答
  • 2021-01-31 01:43

    As per Jonathan's comment:

    variable=$(( 1 == 1 ? 1 : 0 ))  
    

    EDIT:

    I revised the original answer which just echo'd the value of the condition operator, it didn't actually show any assignment.

    0 讨论(0)
  • 2021-01-31 01:43

    In addition to the other more general answers (particularly as per Jonathan's comment and Kevin's more general answer [which also supports strings]) I'd like to add the following two solutions:


    setting the variable to either 0 or 1 based on the condition:

    (as the question's example suggests.)

    The general form would read

    (condition); variable=$?;
    

    where $variable results in being either 0 or 1 and condition can be any valid conditional expression.

    E.g. checking a variable ...

    [[ $variableToCheck == "$othervariable, string or number to match" ]]
    variable=$?
    

    ... or checking a file's existence ...

    [ -f "$filepath" ]
    fileExists=$?
    

    ... or checking the nummerical value of $myNumber:

    (( myNumber >= 1000000000 ))
    is_huge_number=$?
    


    The advantages of this solution is that

    • it supports arbitrary conditional expressions, including strings
      (which are not supported in arithmetic expressions of Jonathan's solution)
    • that variable gets declared in any case, unlike in griffon's answer:
      [ -z "$variable" ] && variable="defaultValue"
      Which would matter in case you want to nameref it later on (e.g. from within a function).


    Please note: In Bash, the special variable $? always contains the exit code of the previously executed statement (or statement block; see the man bash for more details). As such, a positive result is generally represented by the value 0, not 1 (See my comment below, thanks Assimilater for pointing it out). Thus, if the condition is true (e.g [[2 eq 2]]) then $?=0.

    If instead you need 0 or 1 in your variable (e.g. to print or do mathematical calculations) then you need to employ boolean negation using a leading exclamation mark (as pointed out by GypsySpellweaver in the comments below): ( ! condition ); variable=$? or ! ( condition ); variable=$?. (However, readability in terms of what happens might be a bit less obvious.)

    Another possible solution by Jonathan would be variable=$(( 1 == 1 ? 1 : 0 )) - which, however, is creating a subshell.

    If you want to avoid the creation of a subshel, keep good readability or have arbitrary conditions, use one of the following solutions.


    setting the variable to arbitrary values:

    as it is done in most other answers, it could adapted as follows:

    (condition) \
        && variable=true \
        || variable=false
    

    e.g as in

    [[ $variableToCheck == "$othervariable, string or number to match" ]] \
        && variable="$valueIfTrue" \
        || variable="$valueIfFalse"
    

    or to get 1 in a positive check, and 0 upon failure (like in the question's example):

    [[ $variableToCheck == "$othervariable, string or number to match" ]] \
        && variable=1 \
        || variable=0
    

    (for the last example, - as already mentioned in the notes above - the same can be achieved with boolean negation using a leading exclamation mark:

    [[ ! $variableToCheck == "$othervariable, string or number to match" ]]
    variable=$?
    


    The advantages of this solution is that

    • it might be considered a bit better readable than Kevin's answer
      myvar="default" && [[ <some_condition_is_true> ]] && myvar="non-default", and
    • the $valueIfTrue is conditionally evaluated only if needed,
      which would matter in case you'd do something
      • with side-effect, like
        • variable=$((i++)), or
        • { variable=$1; shift; }
      • high computation, like
        • variable=$(find / -type f -name ListOfFilesWithThisNameOnMySystem)
    • is a bit shorter than ghostdog74's answer
      (which, however is great if you have multiple conditions!)
    • does not open a subshell as in Pierre's answer
    • and as above:
      • it supports arbitrary conditional expressions, including strings
        (which are not supported in arithmetic expressions of Jonathan's solution)
      • that variable gets declared in any case, unlike in griffon's answer:
        [ -z "$variable" ] && variable="defaultValue"
        Which would matter in case you want to nameref it later on (e.g. from within a function).
    0 讨论(0)
  • 2021-01-31 01:47
    myvar="default" && [[ <some_condition_is_true> ]]  && myvar="non-default"
    

    real examples:

    DELIM="" && [[ "$APP_ENV_RESOLVED" != "" ]] && DELIM=$INNER_DELIM
    

    The condition can be "(( ... ))" as well:

    filepath=/proc/drbd && (( $# > 0 )) && filepath=$1
    
    0 讨论(0)
  • 2021-01-31 01:47

    another way

    case "$variable" in
      condition ) result=1;;
      *) result=0;;
    esac
    
    0 讨论(0)
  • 2021-01-31 01:49

    If you want to assign a value unless variable is empty use this:

    [ -z "$variable" ] && variable="defaultValue"
    

    You can put as well, each other condition on the []

    0 讨论(0)
  • 2021-01-31 01:50

    If you want a way to define defaults in a shell script, use code like this:

    : ${VAR:="default"}
    

    Yes, the line begins with ':'. I use this in shell scripts so I can override variables in ENV, or use the default.

    This is related because this is my most common use case for that kind of logic. ;]

    0 讨论(0)
提交回复
热议问题