从 Bash 函数返回一个布尔值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5431909/
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
Returning a boolean from a Bash function
提问by luca
I want to write a bash function that check if a file has certain properties and returns true or false. Then I can use it in my scripts in the "if". But what should I return?
我想编写一个 bash 函数来检查文件是否具有某些属性并返回 true 或 false。然后我可以在“if”的脚本中使用它。但是我应该返回什么?
function myfun(){ ... return 0; else return 1; fi;}
then I use it like this:
然后我像这样使用它:
if myfun filename.txt; then ...
of course this doesn't work. How can this be accomplished?
这当然行不通。如何做到这一点?
回答by Erik
Use 0 for true and 1 for false.
使用 0 表示真,1 表示假。
Sample:
样本:
#!/bin/bash
isdirectory() {
if [ -d "" ]
then
# 0 = true
return 0
else
# 1 = false
return 1
fi
}
if isdirectory ; then echo "is directory"; else echo "nopes"; fi
Edit
编辑
From @amichair's comment, these are also possible
从@amichair 的评论来看,这些也是可能的
isdirectory() {
if [ -d "" ]
then
true
else
false
fi
}
isdirectory() {
[ -d "" ]
}
回答by Bruno Bronosky
Why you should care what I say in spite of there being a 250+ upvote answer
尽管有 250 多个赞成票的答案,但为什么你应该关心我说的话
It's not that 0 = true
and 1 = false
. It is: zero means no failure (success)and non-zero means failure (of type N).
不是那个0 = true
和1 = false
。它是:零表示没有失败(成功),非零表示失败(N 型)。
While the selected answeris technically "true" pleasedo not put return 1
** in your code for false. It will have several unfortunate side effects.
虽然所选答案在技术上是“真”,但请不要return 1
在您的代码中为false放置** 。它将有几个不幸的副作用。
- Experienced developers will spot you as an amateur (for the reason below).
- Experienced developers don't do this (for all the reasons below).
- It is error prone.
- Even experienced developers can mistake 0 and 1 as false and true respectively (for the reason above).
- It requires (or will encourage) extraneous and ridiculous comments.
- It's actually less helpful than implicit return statuses.
- 有经验的开发人员会将您视为业余爱好者(原因如下)。
- 有经验的开发人员不会这样做(出于以下所有原因)。
- 它很容易出错。
- 即使是有经验的开发人员也可能将 0 和 1 分别误认为 false 和 true(出于上述原因)。
- 它需要(或将鼓励)无关紧要和荒谬的评论。
- 它实际上不如隐式返回状态有用。
Learn some bash
学习一些 bash
The bash manualsays (emphasis mine)
在bash的手册说(重点煤矿)
return [n]
Cause a shell function to stop executing and return the value n to its caller. If n is not supplied, the return value is the exit status of the last command executedin the function.
返回 [n]
导致 shell 函数停止执行并将值 n 返回给它的调用者。如果未提供 n,则返回值是函数中执行的最后一个命令的退出状态。
Therefore, we don't have to EVER use 0 and 1 to indicate True and False. The fact that they do so is essentially trivial knowledge useful only for debugging code, interview questions, and blowing the minds of newbies.
因此,我们不必使用 0 和 1 来表示 True 和 False。他们这样做的事实本质上是一些琐碎的知识,仅用于调试代码、面试问题和让新手大吃一惊。
The bash manual also says
bash 手册还说
otherwise the function's return status is the exit status of the last command executed
否则函数的返回状态是最后执行的命令的退出状态
The bash manual also says
bash 手册还说
($?) Expands to the exit status of the most recently executed foreground pipeline.
( $?) 扩展到最近执行的前台管道的退出状态。
Whoa, wait. Pipeline? Let's turn to the bash manualone more time.
A pipeline is a sequence of one or more commandsseparated by one of the control operators ‘|' or ‘|&'.
管道是由一个控制运算符“|”分隔的一个或多个命令的序列 或“|&”。
Yes. They said 1 command is a pipeline. Therefore, all 3 of those quotes are saying the same thing.
是的。他们说 1 命令是一个管道。因此,所有这三个引文都在说同样的事情。
$?
tells you what happened last.- It bubbles up.
$?
告诉你最后发生了什么。- 它冒泡了。
My answer
我的答案
So, while @Kambus demonstratedthat with such a simple function, no return
is needed at all. I think
was unrealistically simple compared to the needs of most people who will read this.
因此,虽然@Kambus 证明了使用如此简单的功能,但return
根本不需要。与大多数阅读本文的人的需求相比,我认为这是不切实际的简单。
Why return
?
为什么return
?
If a function is going to return its last command's exit status, why use return
at all? Because it causes a function to stop executing.
如果一个函数要返回其最后一个命令的退出状态,为什么要使用return
呢?因为它会导致函数停止执行。
Stop execution under multiple conditions
在多个条件下停止执行
01 function i_should(){
02 uname="$(uname -a)"
03
04 [[ "$uname" =~ Darwin ]] && return
05
06 if [[ "$uname" =~ Ubuntu ]]; then
07 release="$(lsb_release -a)"
08 [[ "$release" =~ LTS ]]
09 return
10 fi
11
12 false
13 }
14
15 function do_it(){
16 echo "Hello, old friend."
17 }
18
19 if i_should; then
20 do_it
21 fi
What we have here is...
我们这里有...
Line 04
is an explicit[-ish] return true because the RHS of &&
only gets executed if the LHS was true
Line04
是一个显式 [-ish] 返回 true 因为&&
只有在 LHS 为 true 时才会执行RHS
Line 09
returns either true or false matching the status of line 08
Line09
返回匹配 line 状态的 true 或 false08
Line 13
returns false because of line 12
线13
返回,因为线的错误12
(Yes, this can be golfed down, but the entire example is contrived.)
(是的,这可以打高尔夫球,但整个例子都是人为的。)
Another common pattern
另一种常见模式
# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
echo "some_command failed"
fi
# Do this...
some_command
status=$?
if ! $(exit $status); then
echo "some_command failed"
fi
Notice how setting a status
variable demystifies the meaning of $?
. (Of course you know what $?
means, but someone less knowledgeable than you will have to Google it some day. Unless your code is doing high frequency trading, show some love, set the variable.) But the real take-away is that "if not exist status" or conversely "if exit status" can be read out loud and explain their meaning. However,that last one may be a bit too ambitious because seeing the word exit
might make you think it is exiting the script, when in reality it is exiting the $(...)
subshell.
请注意设置status
变量如何揭开$?
. (当然你知道是什么$?
意思,但比你知识渊博的人总有一天会不得不去谷歌它。除非你的代码在做高频交易,表现出一些爱,设置变量。)但真正的收获是“如果不存在状态”或相反的“如果退出状态”可以大声读出并解释它们的含义。然而,最后一个可能有点过于雄心勃勃,因为看到这个词exit
可能会让你认为它正在退出脚本,而实际上它正在退出$(...)
子 shell。
** If you absolutely insist on using return 1
for false, I suggest you at least use return 255
instead. This will cause your future self, or any other developer who must maintain your code to question "why is that 255?" Then they will at least be paying attention and have a better chance of avoiding a mistake.
** 如果你绝对坚持使用return 1
for false,我建议你至少使用它return 255
代替。这将导致您未来的自己或任何其他必须维护您的代码的开发人员质疑“为什么是 255?” 然后他们至少会注意并有更好的机会避免错误。
回答by Kambus
myfun(){
[ -d "" ]
}
if myfun "path"; then
echo yes
fi
# or
myfun "path" && echo yes
回答by RenRen
Be careful when checking directory only with option -d !
if variable $1 is empty the check will still be successfull. To be sure, check also that the variable is not empty.
仅使用选项 -d 检查目录时要小心!
如果变量 $1 为空,检查仍然会成功。当然,还要检查变量是否为空。
#! /bin/bash
is_directory(){
if [[ -d ]] && [[ -n ]] ; then
return 0
else
return 1
fi
}
#Test
if is_directory ; then
echo "Directory exist"
else
echo "Directory does not exist!"
fi
回答by BuvinJ
I encountered a point (not explictly yet mentioned?) which I was stumbling over. That is, not how to returnthe boolean, but rather how to correctly evaluate it!
我遇到了一个问题(还没有明确提到?),这是我绊倒的。也就是说,不是如何返回布尔值,而是如何正确评估它!
I was trying to say if [ myfunc ]; then ...
, but that's simply wrong. You must not use the brackets! if myfunc; then ...
is the way to do it.
我想说if [ myfunc ]; then ...
,但那完全是错误的。你不能使用括号!if myfunc; then ...
是这样做的方法。
As at @Bruno and others reiterated, true
and false
are commands, not values! That's very important to understanding booleans in shell scripts.
截至@Bruno和其他重申,true
并且false
是命令,不重视!这对于理解 shell 脚本中的布尔值非常重要。
In this post, I explained and demoed using boolean variables: https://stackoverflow.com/a/55174008/3220983. I strongly suggest checking that out, because it's so closely related.
在这篇文章中,我使用布尔变量进行了解释和演示:https: //stackoverflow.com/a/55174008/3220983。我强烈建议检查一下,因为它是如此密切相关。
Here, I'll provide some examples of returning and evaluatingbooleans from functions:
在这里,我将提供一些从函数返回和评估布尔值的示例:
This:
这个:
test(){ false; }
if test; then echo "it is"; fi
Produces no echo output. (i.e. false
returnsfalse)
不产生回声输出。(即false
返回假)
test(){ true; }
if test; then echo "it is"; fi
Produces:
产生:
it is
(i.e. true
returnstrue)
(即true
返回真)
And
和
test(){ x=1; }
if test; then echo "it is"; fi
Produces:
产生:
it is
Because 0 (i.e. true) was returned implicitly.
因为 0(即 true)是隐式返回的。
Now, this is what was screwing me up...
现在,这就是让我搞砸的事情......
test(){ true; }
if [ test ]; then echo "it is"; fi
Produces:
产生:
it is
AND
和
test(){ false; }
if [ test ]; then echo "it is"; fi
ALSO produces:
还生产:
it is
Using the brackets here produced a false positive! (I infer the "outer" command result is 0.)
在这里使用括号会产生误报!(我推断“外部”命令结果为 0。)
The major take away from my post is: don't use brackets to evaluate a boolean function (or variable) like you would for a typical equality check e.g. if [ x -eq 1 ]; then...
!
我的帖子的主要内容是:不要像典型的相等性检查一样使用括号来评估布尔函数(或变量),例如if [ x -eq 1 ]; then...
!
回答by mrteatime
Use the true
or false
commands immediately before your return
, then return
with no parameters. The return
will automatically use the value of your last command.
在您的 之前使用true
orfalse
命令return
,然后return
不带参数。该return
会自动使用你的最后一个命令的值。
Providing arguments to return
is inconsistent, type specific and prone to error if you are not using 1 or 0. And as previous comments have stated, using 1 or 0 here is not the right way to approach this function.
return
如果您不使用 1 或 0 ,则提供的参数不一致、类型特定且容易出错。正如之前的评论所述,此处使用 1 或 0 不是处理此函数的正确方法。
#!/bin/bash
function test_for_cat {
if [ = "cat" ];
then
true
return
else
false
return
fi
}
for i in cat hat;
do
echo "${i}:"
if test_for_cat "${i}";
then
echo "- True"
else
echo "- False"
fi
done
Output:
输出:
$ bash bash_return.sh
cat:
- True
hat:
- False
回答by Nephew
It might work if you rewrite this
function myfun(){ ... return 0; else return 1; fi;}
as this function myfun(){ ... return; else false; fi;}
. That is if false
is the last instruction in the function you get false result for whole function but return
interrupts function with true result anyway. I believe it's true for my bash interpreter at least.
如果您将其重写function myfun(){ ... return 0; else return 1; fi;}
为 this ,它可能会起作用
function myfun(){ ... return; else false; fi;}
。也就是说,如果false
是函数中的最后一条指令,您会得到整个函数的错误结果,但return
无论如何都会以正确的结果中断函数。我相信至少对我的 bash 解释器来说是这样。
回答by Roy Shilkrot
I found the shortest form to test the function output is simply
我发现测试函数输出的最短形式很简单
do_something() {
[[ -e ]] # e.g. test file exists
}
do_something "myfile.txt" || { echo "File doesn't exist!"; exit 1; }
回答by Charlie
For code readability reasons I believe returning true/false should:
出于代码可读性的原因,我认为返回 true/false 应该:
- be on one line
- be one command
- be easy to remember
- mention the keyword
return
followed by another keyword (true
orfalse
)
- 在一条线上
- 成为一个命令
- 容易记住
- 提及关键字
return
后跟另一个关键字(true
或false
)
My solution is return $(true)
or return $(false)
as shown:
我的解决方案是return $(true)
或return $(false)
如图所示:
is_directory()
{
if [ -d "" ]; then
return $(true)
else
return $(false)
fi
}
回答by BuvinJ
Following up on @Bruno Bronosky and @mrteatime, I offer the suggestion that you just write your boolean return "backwards". This is what I mean:
跟进@Bruno Bronosky 和@mrteatime,我建议您只需“向后”编写布尔返回值。这就是我的意思:
foo()
{
if [ "" == "bar" ]; then
true; return
else
false; return
fi;
}
That eliminates the ugly two line requirement for every return statement.
这消除了每个 return 语句的丑陋的两行要求。