当前位置: 首页 > 科技观察

Bash中的逻辑与(&)

时间:2023-03-13 23:05:40 科技观察

在Bash中,您可以使用&作为AND(逻辑与)运算符。有人可能会认为两篇文章中的&表示相同的意思,但事实并非如此。虽然第一篇文章讨论了如何在命令末尾使用&来后台运行命令,然后分析进程管理,但是第二篇文章将&视为一种引用文件描述符的方法。这些文章让我们知道,结合<和>,您可以直接在别处输入或输出。但是我们还没有接触过&作为AND运算符。那么,让我们来看看吧。&是按位运算符如果您对二进制数运算非常熟悉,那么您一定听说过AND和OR。这些是按位运算,对二进制数的各个位进行运算。在Bash中,使用&作为AND运算符和|作为OR运算符:AND:0&0=00&1=01&0=01&1=1OR:0|0=00|1=11|0=11|1=1你可以与任意两个数字并回显结果:$echo$((2&3))#00000010AND00000011=000000102$echo$((120&97))#01111000同样适用于AND01100001=0110000096OR(|):$echo$((2|3))#00000010OR00000011=000000113$echo$((120|97))#01111000OR01100001=0111001(...))告诉Bashdouble之间的内容括号是某种算术或逻辑运算。((2+2))、((5%2))(%是模运算符)和(((5%2)+1))(等于3)都有效。与变量一样,使用$提取值以便您可以使用它。空格无效:((2+3))等同于((2+3))和((2+3))。Bash只能对整数进行运算。试试这个:((5/2)),你会得到2;或者这个((2.5&7)),但是你会得到一个错误。然后,在按位运算中使用整数以外的任何东西(这就是我们现在谈论的)通常是您不应该做的事情。提示:如果您想查看十进制数在二进制中的样子,可以使用bc,这是一个预装在大多数Linux发行版中的命令行计算器。例如:bc<<<"obase=2;97"会将97转为十进制(obase中的o代表“output”,即“输出”)。bc<<<"ibase=2;11001011"会将11001011转为十进制(ibase中的i代表“输入”,即“输入”)。&&是逻辑运算符尽管它使用与其按位表示相同的逻辑原则,但Bash的&&运算符只能呈现两个结果:1(“真值”)和0(“假值”)。对于Bash,任何不为0的数字都是“真值”,任何等于0的数字都是“假值”。什么也是“假值”而不是数字:$echo$((4&&5))#两个非零数字,都是true=true1$echo$((0&&5))#一个是零,一个是false=false0$echo$((b&&5))#其中一个不是数字,一个是false=false0类似于&&,OR对应||,用法和你想的一样。以上所有内容都很简单......直到它用于命令的退出状态。&&是命令退出状态的逻辑运算符正如我们在上一篇文章中看到的,当命令运行时,它会输出一条错误消息。更何况今天的讨论,它最后还输出了一个数字。这个数字称为“返回代码”,如果为0,则表示该命令在执行过程中没有遇到任何问题。如果是任何其他数字,即使命令完成,也意味着出现问题。所以0表示是,任何其他数字表示出现问题,并且在返回代码的上下文中,0表示“真”,任何其他数字表示“假”。正确的!这与您所知道的逻辑运算完全相反,但是您可以用它做什么呢?不同的背景,不同的规则。这种用处很快就会显现出来。让我们继续吧!返回码暂时存储在特殊变量?--是的,我知道:又一个令人困惑的选择。但是不管怎样,不要忘记我们在讨论变量的那篇文章中说过,当我们说应该使用$符号来读取变量中的值时,这里也是一样的。所以,如果你想知道一个命令运行是否顺利,你需要使用$?读取?的值在命令结束后和运行其他命令之前立即变量。尝试以下命令:$find/etc-iname"*.service"find:'/etc/audisp/plugins.d':Permissiondenied/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service/etc/systemd/system/dbus-org.freedesktop.ModemManager1.service[…]正如您在上一篇文章中所见,以普通用户权限在/etc下运行find通常会抛出错误,因为它正在尝试读取您没有读取的子目录有访问权限。所以,如果你在执行find后立即执行...echo$?...,它将打印1,表示出现错误。(注意:当你在一行上运行两次echo$?时,你会得到一个0。这是因为$?将包含第一个echo$?的返回码,这应该会成功。所以第一课学习如何使用$?是:单独执行$?或将其存储在其他安全的地方-例如在变量中,否则您会很快丢失它。)的一种用法?variable直接将其合并到命令链表中,这样如果Bash在运行命令链时任何操作失败,后续命令将终止。例如,您可能熟悉构建和编译应用程序源代码的过程。你可以像这样一个一个地手动运行它们:$configure...$make...$makeinstall...你也可以将这三行组合成一行...制作;makeinstall...但你必须希望上帝保佑你。为什么这样说呢?因为你有这样做的缺点,例如,如果configure失败,Bash仍然会尝试执行make和sudomakeinstall-即使没有什么可做的,实际上什么也不会安装。更明智的做法是:$configure&&make&&makeinstall这将从每个命令中获取退出代码并将其用作链式&&操作的操作数。但是,不用抱怨,Bash知道如果configure返回一个非零结果,整个事情就会失败。如果发生这种情况,您不必运行make来检查它的退出代码,因为它无论如何都会失败。因此,它放弃运行make并仅将非零结果传递给下一个操作。而且,由于configure&&make传递错误,Bash也不必运行makeinstall。这意味着,在一长串命令中,您可以将它们与&&连接起来,如果失败,您可以节省时间,因为其他命令会立即取消。您可以类似地使用||,OR逻辑运算符,这样即使只有部分命令成功,Bash也会运行下一个链接命令。鉴于所有这些(以及我们之前介绍的内容),您现在应该更清楚地了解我们在本文开头出现的命令行:mkdirtest_dir2>/dev/null||触摸backup/dir/images.txt&&找到.-iname"*jpg">backup/dir/images.txt&所以,假设你从一个有读写权限的目录运行上面的命令,它做了什么以及它是如何做的?它如何避免不合时宜且可能中断执行的错误?下周,除了为您提供这些答案的结果外,我们还将讨论括号,所以不要错过!