如何测试字符串和整数相等,并与逻辑 && 结合使用和 || bash 中的运算符?
我有几个变量,我想检查以下条件(用文字写出来,然后是我在 bash 脚本方面的失败尝试):
if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then
do something
done.
在我失败的尝试中,我想出了:
if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) );
then
scale=0.05
fi
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):
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你所写的实际上几乎可以工作(如果所有变量都是数字,它就会工作),但这根本不是一种惯用的方式。
(…)
括号表示 子 shell< /a>.它们的内部内容与许多其他语言中的表达方式不同。它是一个命令列表(就像括号外一样)。这些命令在单独的子进程中执行,因此在括号内执行的任何重定向、赋值等在括号外都不起作用。$(…)
是一个 命令替换:括号内有一个命令,该命令的输出用作命令行的一部分(经过额外的扩展,除非替换是在双引号之间,但那就是<一href="https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters">另一个故事)。{ … }
大括号类似于括号,它们对命令进行分组,但它们只影响解析,而不影响分组。程序x=2; { x=4; }; echo $x
打印 4,而x=2; (x=4); echo $x
打印 2。(大括号还需要在其周围有空格,并且在结束之前有分号,而括号则不需要。这只是一个语法怪癖。)${VAR}
是一个参数扩展,扩展到变量的值,并可能进行额外的转换。((…))
双括号包围 算术指令,即整数计算,其语法类似于其他编程语言。此语法主要用于赋值和条件语句。$((…))
使用相同的语法,它扩展为表达式的整数值。[[ … ]]
双括号包围 条件表达式。条件表达式主要构建在运算符上,例如-n $variable
测试变量是否为空,-e $file
测试文件是否存在。还有字符串相等运算符:"$string1" == "$string2"
(注意右侧是一个模式,例如[[ $foo == a* ]]
测试$foo
是否以a
开头,而[[ $foo == "a*" ]]
测试是否$foo
正是a*
),以及熟悉的!
、&&
和||
运算符(用于否定、合取和析取)以及用于分组的括号。请注意,每个运算符周围都需要一个空格(例如[[ "$x" == "$y" ]]
,而不是),以及括号内部和外部的空格或类似[[ "$x"=="$ y" ]]
;
的字符(例如[[ -n $foo ]],而不是
)。<代码>[[-n $foo]][ … ]
单括号是条件表达式的另一种形式,具有更多怪癖(但更旧且更便携)。暂时不要写;当您发现包含它们的脚本时,请开始担心它们。这是在 bash 中编写测试的惯用方法:
如果您需要可移植到其他 shell,则可以这样做:(
注意每个单独测试周围的附加引用和单独的括号组,以及传统
=
运算符而不是 ksh/bash/zsh==
变体)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.$(…)
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 programx=2; { x=4; }; echo $x
prints 4, whereasx=2; (x=4); echo $x
prints 2. (Also braces require spaces around them and a semicolon before closing, whereas parentheses don't. That's just a syntax quirk.)${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.$((…))
, which expand to the integer value of the expression.[[ … ]]
double brackets surround conditional expressions. Conditional expressions are mostly built on operators such as-n $variable
to test if a variable is empty and-e $file
to 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$foo
starts witha
while[[ $foo == "a*" ]]
tests if$foo
is exactlya*
), 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), and a space or a character like[[ "$x"=="$y" ]]
;
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.This is the idiomatic way to write your test in bash:
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)非常接近。
应该有效。
分解一下,
就是整数比较,
while
是字符串比较。
否则,我只是正确地对比较进行分组。
双方括号分隔条件表达式。而且,我发现以下内容是关于该主题的好读物: “(IBM)揭秘测试,[,[[,((和 if-then-else”
It is very close.
should work.
Breaking it down,
is an integer comparison,
whereas
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"
一个非常便携的版本(甚至是旧版 Bourne shell):
这具有仅运行的额外质量最多一个子进程(即进程
[
),无论 shell 风格如何。如果变量包含数值,则将
=
替换为-eq
,例如3 -eq 03
为 true,但3 = 03
> 是假的。 (字符串比较)A very portable version (even to legacy Bourne shell):
This has the additional quality of running only one subprocess at most (which is the process
[
), whatever the shell flavor.Replace
=
with-eq
if variables contain numeric values, e.g.3 -eq 03
is true, but3 = 03
is false. (string comparison)以下是 if-then-else 语句的简短版本的代码:
请注意以下内容:
||
和&& if 条件内的
操作数(即圆括号之间)是逻辑操作数(或/和)||
和&&
位于 if 条件之外的操作数表示 then/else实际上,该语句表示:
if (a=1 或 b=2) then "ok" else "nok"
Here is the code for the short version of the if-then-else statement:
Pay attention to the following:
||
and&&
operands inside the if condition (i.e., between round parentheses) are logical operands (or/and)||
and&&
operands outside the if condition mean then/elsePractically, the statement says:
if (a=1 or b=2) then "ok" else "nok"