Bash 中的简单逻辑运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6270440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:37:09  来源:igfitidea点击:

Simple logical operators in Bash

bashlogical-operators

提问by Amit

I have a couple of variables and I want to check the following condition (written out in words, then my failed attempt at bash scripting):

我有几个变量,我想检查以下条件(用文字写出来,然后我尝试编写 bash 脚本失败):

if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then 

do something

done.

And in my failed attempt, I came up with:

在我失败的尝试中,我想出了:

if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) ); 
  then
    scale=0.05
  fi

回答by Gilles 'SO- stop being evil'

What you've written actually almost works (it would work if all the variables were numbers), but it's not an idiomatic way at all.

你写的东西实际上几乎可以工作(如果所有变量都是数字,它就会工作),但这根本不是惯用的方式。

  • (…)parentheses indicate a subshell. What's inside them isn't an expression like in many other languages. It's a list of commands (just like outside parentheses). These commands are executed in a separate subprocess, so any redirection, assignment, etc. performed inside the parentheses has no effect outside the parentheses.
    • With a leading dollar sign, $(…)is a command substitution: there is a command inside the parentheses, and the output from the command is used as part of the command line (after extra expansions unless the substitution is between double quotes, but that's another story).
  • { … }braces are like parentheses in that they group commands, but they only influence parsing, not grouping. The program x=2; { x=4; }; echo $xprints 4, whereas x=2; (x=4); echo $xprints 2. (Also braces require spaces around them and a semicolon before closing, whereas parentheses don't. That's just a syntax quirk.)
    • With a leading dollar sign, ${VAR}is a parameter expansion, expanding to the value of a variable, with possible extra transformations.
  • ((…))double parentheses surround an arithmetic instruction, that is, a computation on integers, with a syntax resembling other programming languages. This syntax is mostly used for assignments and in conditionals.
    • The same syntax is used in arithmetic expressions $((…)), which expand to the integer value of the expression.
  • [[ … ]]double brackets surround conditional expressions. Conditional expressions are mostly built on operatorssuch as -n $variableto test if a variable is empty and -e $fileto test if a file exists. There are also string equality operators: "$string1" == "$string2"(beware that the right-hand side is a pattern, e.g. [[ $foo == a* ]]tests if $foostarts with awhile [[ $foo == "a*" ]]tests if $foois exactly a*), and the familiar !, &&and ||operators for negation, conjunction and disjunction as well as parentheses for grouping. Note that you need a space around each operator (e.g. [[ "$x" == "$y" ]], not [[ "$x"=="$y" ]]), and a space or a character like ;both inside and outside the brackets (e.g. [[ -n $foo ]], not [[-n $foo]]).
  • [ … ]single brackets are an alternate form of conditional expressions with more quirks (but older and more portable). Don't write any for now; start worrying about them when you find scripts that contain them.
  • (…)括号表示子shell。它们内部的内容与许多其他语言中的表达方式不同。它是一个命令列表(就像外面的括号一样)。这些命令在单独的子进程中执行,因此在括号内执行的任何重定向、赋值等在括号外都不起作用。
    • 前导美元符号$(…)命令替换:括号内有一个命令,命令的输出用作命令行的一部分(在额外扩展之后,除非替换在双引号之间,但那是另一回事了) .
  • { … }大括号就像括号,因为它们对命令进行分组,但它们只影响解析,而不影响分组。程序x=2; { x=4; }; echo $x打印 4,而x=2; (x=4); echo $x打印 2。(同样大括号需要在它们周围有空格和分号才能关闭,而括号则不需要。这只是一个语法怪癖。)
    • 带前导美元符号的${VAR}参数扩展,扩展到变量的值,可能有额外的转换。
  • ((…))双括号包围算术指令,即整数计算,其语法类似于其他编程语言。这种语法主要用于赋值和条件。
    • 在算术表达式中使用相同的语法$((…)),它扩展为表达式的整数值。
  • [[ … ]]双括号包围条件表达式。条件表达式主要建立在运算符之上,例如-n $variable测试变量是否为空以及-e $file测试文件是否存在。还有字符串相等运算符:("$string1" == "$string2"请注意右侧是一个模式,例如[[ $foo == a* ]]测试是否$fooawhile开始[[ $foo == "a*" ]]测试是否$foo恰好是a*),以及用于否定、连接和析取的常见!,&&||运算符以及用于分组的括号。请注意,您需要在每个运算符周围留一个空格(例如[[ "$x" == "$y" ]],not [[ "$x"=="$y" ]]),并且;在括号的内部和外部都需要一个空格或一个字符(例如[[ -n $foo ]],not[[-n $foo]])。
  • [ … ]单括号是条件表达式的另一种形式,具有更多的怪癖(但更旧且更便携)。暂时不要写任何东西;当您找到包含它们的脚本时,就开始担心它们。

This is the idiomatic way to write your test in bash:

这是在 bash 中编写测试的惯用方法:

if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then

If you need portability to other shells, this would be the way (note the additional quoting and the separate sets of brackets around each individual test, and the use of the traditional =operator rather than the ksh/bash/zsh ==variant):

如果您需要可移植到其他 shell,这将是方法(注意每个单独测试周围的附加引用和单独的括号集,以及使用传统=运算符而不是 ksh/bash/zsh==变体):

if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then

回答by matchew

very close

很接近

if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]]; 
  then 
    scale=0.05
  fi

should work.

应该管用。

breaking it down

分解它

[[ $varA -eq 1 ]] 

is an integer comparison where as

是一个整数比较,其中

$varB == 't1'

is a string comparison. otherwise, I am just grouping the comparisons correctly.

是字符串比较。否则,我只是正确地对比较进行分组。

Double square brackets delimit a Conditional Expression. And, I find the following to be a good reading on the subject: "(IBM) Demystify test, [, [[, ((, and if-then-else"

双方括号分隔条件表达式。而且,我发现以下内容是有关该主题的很好的读物:“(IBM) Demystify test, [, [[, ((, and if-then-else ”)

回答by J.P. Tosoni

A very portable version (even to legacy bourne shell):

一个非常便携的版本(即使是传统的 bourne shell):

if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
then    do-something
fi

This has the additional quality of running only one subprocess at most (which is the process '['), whatever the shell flavor.

这具有最多仅运行一个子进程(即进程 '[')的附加质量,无论 shell 风格如何。

Replace "=" with "-eq" if variables contain numeric values, e.g.

如果变量包含数值,请用“-eq”替换“=”,例如

  • 3 -eq 03 is true, but
  • 3 = 03 is false. (string comparison)
  • 3 -eq 03 是真的,但是
  • 3 = 03 为假。(字符串比较)

回答by tlc

Here is the code for the short version of if-then-else statement:

这是 if-then-else 语句的简短版本的代码:

( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"

Pay attention to the following:

请注意以下事项:

  1. ||and &&operands inside if condition (i.e. between round parentheses) are logical operands (or/and)

  2. ||and &&operands outside if condition mean then/else

  1. ||&&if 条件内的操作数(即圆括号之间)是逻辑操作数(或/和)

  2. ||&&如果条件意味着 then/else和外部操作数

Practically the statement says:

实际上,该声明说:

if (a=1 or b=2) then "ok" else "nok"

if (a=1 or b=2) then "ok" else "nok"

回答by AlikElzin-kilaka

if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
    echo STR is empty but should have a value.
fi