如何在 Bash 中使用布尔值编写 if/else?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43152781/
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
How can I write if/else with Boolean in Bash?
提问by Gordon Davisson
How can I write an 'if then' statement to switch between these to variables as in the following?
如何编写“if then”语句以在这些变量之间切换,如下所示?
if(switch){
server_var_shortname=$server_shared_shortname
server_var=$server_shared
server_var_bare=$server_shared_bare
} else {
server_var_shortname=$server_vps_shortname
server_var=$server_vps
server_var_bare=$server_vps_bare
}
I'm not familiar with Bash syntax and basically just need an 'if/else' statement on a Boolean. Also, can I use true / false values as such? Also how do I do the 'else' statement?
我不熟悉 Bash 语法,基本上只需要一个关于布尔值的“if/else”语句。另外,我可以使用真/假值吗?另外我如何做'else'语句?
$switch=true;
if $switch
then
server_var_shortname=$server_shared_shortname
server_var=$server_shared
server_var_bare=$server_shared_bare
fi
回答by Gordon Davisson
First, shells (including Bash) don't have Booleans; they don't even have integers (although they can sort of fake it). Mostly, they have strings.
首先,shell(包括 Bash)没有布尔值;他们甚至没有整数(尽管他们可以伪造它)。大多数情况下,它们都有字符串。
Bash also has arrays... of strings. There are a number of ways of faking Booleans; my favorite is to use the strings "true" and "false". These also happen to be the names of commands that always succeed and fail respectively, which comes in handy, because the if
statement actually takes a command, and runs the then
clause if it succeeds and the else
clause if it fails. Thus, you can "run" the Boolean, and it'll succeed if set to "true" and fail if set to "false". Like this:
Bash 也有数组...字符串。有多种方法可以伪造布尔值;我最喜欢使用字符串“true”和“false”。这些也恰好分别是总是成功和失败的命令的名称,派上用场,因为if
语句实际上接受一个命令,then
如果成功则运行else
子句,如果失败则运行子句。因此,您可以“运行”布尔值,如果设置为“true”,它将成功,如果设置为“false”,它将失败。像这样:
switch=true # This doesn't have quotes around it, but it's a string anyway.
# ...
if $switch; then
server_var_shortname=$server_shared_shortname
server_var=$server_shared
server_var_bare=$server_shared_bare
else
server_var_shortname=$server_vps_shortname
server_var=$server_vps
server_var_bare=$server_vps_bare
fi
Note that the more usual format you'll see for if
has square-brackets, like if [ something ]; then
. In this case, [
is actually a command (notsome funny sort of grouping operator) that evaluates its argument as an expression; thus [ "some string" = "some other string" ]
is a command that will fail because the strings aren't equal. You could use if [ "$switch" = true ]; then
, but I prefer to cheat and use the fake Boolean directly.
请注意,您将看到的更常见的格式if
具有方括号,例如if [ something ]; then
. 在这种情况下,[
实际上是一个命令(不是某种有趣的分组运算符),它将其参数计算为表达式;因此[ "some string" = "some other string" ]
是一个将失败的命令,因为字符串不相等。您可以使用if [ "$switch" = true ]; then
,但我更喜欢作弊并直接使用假布尔值。
Caveat: if you do use the cheat I'm suggesting, make sure your "Boolean" variable is set to either "true" or "false" -- not unset, not set to something else. If it's set to anything else, I take no responsibility for the results.
警告:如果您确实使用了我建议的作弊方法,请确保您的“Boolean”变量设置为“true”或“false”——不要未设置,也不要设置为其他内容。如果设置为其他任何内容,我对结果不承担任何责任。
Some other syntax notes:
其他一些语法说明:
- Use
$
on variables when fetching their values, notwhen assigning to them. You have$switch=true;
up there, which will get you an error. - Also, you have a semicolon at the end of that line. This is unnecessary; semicolons are used to separate multiple commands on the same line (and a few other places), but they aren't needed to end the last (/only) command on a line.
The
[
command (which is also known astest
) has a kind of weird syntax. Mostly because it's a command, so it goes through the usual command parsing, so e.g.[ 5 > 19 ]
is parsed as[ 5 ]
with output sent to a file named "19" (and is then true, because "5" is nonblank).[ 5 ">" 19 ]
is better, but still evaluates to true because>
does string (alphabetical) comparisons, and "5" is alphabetically after "19".[ 5 -gt 19 ]
does the expected thing.There's also
[[ ]]
(similar, but cleaner syntax and not available in all shells) and(( ))
(for math, not strings; also not in all shells). See Bash FAQ #31.Putting commands in variables is generally a bad idea. See Bash FAQ #50.
- shellcheck.netis your friend.
$
在获取它们的值时使用变量,而不是在分配给它们时使用。你在$switch=true;
那里,这会让你出错。- 此外,您在该行的末尾有一个分号。这是不必要的;分号用于分隔同一行(和其他一些地方)上的多个命令,但不需要它们来结束一行上的最后一个(/仅)命令。
的
[
命令(其也被称为test
)具有一种奇怪的语法。主要是因为它是一个命令,所以它经历了通常的命令解析,所以 eg[ 5 > 19 ]
被解析为[ 5 ]
将输出发送到名为“19”的文件(然后为真,因为“5”是非空白的)。[ 5 ">" 19 ]
更好,但仍然评估为真,因为进行>
字符串(按字母顺序)比较,并且“5”按字母顺序排列在“19”之后。[ 5 -gt 19 ]
做预期的事情。还有
[[ ]]
(类似但更简洁的语法,并非在所有 shell 中都可用)和(( ))
(对于数学,不是字符串;也不是在所有 shell 中)。请参阅Bash 常见问题 #31。将命令放在变量中通常是一个坏主意。请参阅Bash 常见问题 #50。
- shellcheck.net是您的朋友。
回答by codeforester
Bash doesn't have any concept of Boolean - there are no true / false values. The construct
Bash 没有任何布尔值的概念——没有真/假值。构造
[ $switch ]
will be true except when switch
variable is not set or is set to an empty string.
除非switch
变量未设置或设置为空字符串,否则为真。
[ ] && echo yes # Nothing is echoed
[ "" ] && echo yes # Nothing is echoed
unset switch && [ $switch ] && echo yes # Nothing is echoed
switch=1 && [ $switch ] && echo yes # 'yes' is echoed
switch=0 && [ $switch ] && echo yes # 'yes' is echoed - the shell makes no distinction of contents - it is true as long it is not empty
See also:
也可以看看:
回答by suleiman
Here is a good guide for If else
. But I want to show a different approach (which you will find also in the link on page 3).
这是一个很好的指南If else
。但我想展示一种不同的方法(您也可以在第 3 页的链接中找到)。
Your coding looks like JavaScript, so I think with Switch
you could also mean the case
command instead of if
. Switch
in JavaScript is similar to case
within a shell, but there isn't any method to check for Booleans. You can check string values for like true
and false
, and you can check for numbers.
你的编码看起来像 JavaScript,所以我认为Switch
你也可以指case
命令而不是if
. Switch
在 JavaScript 中类似于case
在 shell 中,但没有任何方法来检查布尔值。您可以检查 liketrue
和 的字符串值false
,也可以检查数字。
Example...
例子...
#!/bin/bash
case "$Variable" in
false|0|"")
echo "Boolean is set to false."
;;
*)
echo "Boolean is set to true."
;;
esac
Addition
添加
Keep in mind, there are many programs and tools that uses Boolean values
in different forms.
请记住,有许多程序和工具Boolean values
以不同的形式使用。
Two examples...
SQL in general uses numbers as Boolean.
JavaScript uses true and false values.
两个例子...
SQL 通常使用数字作为布尔值。
JavaScript 使用 true 和 false 值。
Meaning: Your Bash script has to know the format of Booleans, before processing them!
含义:在处理布尔值之前,您的 Bash 脚本必须知道它们的格式!
回答by Fred
You need something like this:
你需要这样的东西:
if
CONDITION_SEE_BELOW
then
server_var_shortname=$server_shared_shortname
server_var=$server_shared
server_var_bare=$server_shared_bare
else
server_var_shortname=$server_vps_shortname
server_var=$server_vps
server_var_bare=$server_vps_bare
fi
In Bash (and other shells), the CONDITION_SEE_BELOW
part has to be a command. A command returns a numerical value, and by convention 0
means "true" and any non-zero value means "false". The then
clause will execute if the command returns 0
, or the else
clause in all other cases. The return value is notthe text output by the command. In shells, you can access it with the special variable expansion $?
right after executing a command.
在 Bash(和其他 shell)中,该CONDITION_SEE_BELOW
部分必须是命令。命令返回一个数值,按照惯例0
表示“真”,任何非零值表示“假”。then
如果命令返回0
,则该子句将执行,或者else
在所有其他情况下执行该子句。返回值不是命令输出的文本。在 shell 中,您可以$?
在执行命令后立即使用特殊的变量扩展来访问它。
You can test that with commands true
and false
, which do one thing: generate a zero (true
) and non-zero (false
) return value. Try this at the command line:
您可以使用命令true
and测试它false
,它们只做一件事:生成零 ( true
) 和非零 ( false
) 返回值。在命令行试试这个:
true ; echo "true returns $?"
false ; echo "false returns $?"
You can use any command you want in a condition. There are two commands in particular that have been created with the idea of defining conditions: the classic test command [ ]
(the actual command only being the opening bracket, which is also available as the test
command), and the double-bracketed, Bash-specific [[ ]]
(which is not technically a command, but rather special shell syntax).
您可以在条件中使用任何您想要的命令。特别是有两个命令是根据定义条件的想法创建的:经典的 test 命令[ ]
(实际命令只是左括号,也可用作test
命令)和双括号的 Bash 特定命令[[ ]]
(这在技术上不是命令,而是特殊的 shell 语法)。
For instance, say your switch
variable contains either nothing (null string), or something (string with at least one character), and assume in your case you mean a null string to be "false" and any other string to be "true". Then you could use as a condition:
例如,假设您的switch
变量不包含任何内容(空字符串)或某些内容(至少包含一个字符的字符串),并假设在您的情况下,您的意思是一个空字符串为“false”,而任何其他字符串为“true”。然后你可以使用作为条件:
[ "$switch" ]
If you are OK with a string containing only spaces and tabs to be considered empty (which will happen as a result of standard shell expansion and word splitting of arguments to a command), then you may remove the double quotes.
如果您可以将仅包含空格和制表符的字符串视为空字符串(这是标准 shell 扩展和命令参数分词的结果),那么您可以删除双引号。
The double-bracket test command is mostly similar, but has some nice things about it, including double-quoting not being needed most of the time, supporting Boolean logic with &&
and ||
inside the expression, and having regular expression matching as a feature. It is, however a Bashism.
双括号测试命令大多相似,但有一些不错的地方,包括大多数时候不需要双引号,支持表达式内部&&
和||
内部的布尔逻辑,以及将正则表达式匹配作为一项功能。然而,它是一种巴什主义。
You can use this as a reference to various tests that can be performed with both test commands:
您可以将其用作可以使用两个测试命令执行的各种测试的参考:
6.4 Bash Conditional Expressions
If at all interested in shell programming, be sure to find out about the various tests you can use, as you are likely to be using many of them frequently.
如果对 shell 编程感兴趣,请务必了解您可以使用的各种测试,因为您可能会经常使用其中的许多测试。
回答by jm666
As addition to Gordon's excellent answer, in Bash you can also use the double-parentheses construct. It works for integers, and it is the closest form to other languages. Demo:
除了戈登的出色回答,在 Bash 中,您还可以使用双括号结构。它适用于整数,是与其他语言最接近的形式。演示:
for i in {-2..2}; do
printf "for %s " "$i"
if (( i )) # You can omit the `$`
then
echo is nonzero
else
echo is zero
fi
done
Output:
输出:
for -2 is nonzero
for -1 is nonzero
for 0 is zero
for 1 is nonzero
for 2 is nonzero
You can use any arithmetic operations inside, e.g.:
您可以在内部使用任何算术运算,例如:
for i in {1..6}; do
printf "for %s " "$i"
if (( i % 2 )) #modulo
then
echo odd
else
echo even
fi
done
Output
输出
for 1 odd
for 2 even
for 3 odd
for 4 even
for 5 odd
for 6 even