什么是操作员!=在shell脚本中表示?

eblbsuwk  于 2023-05-23  发布在  Shell
关注(0)|答案(2)|浏览(140)

在这里,我在第二个if语句中有一个感叹号,为什么要使用这个。

#!/bin/bash

name=$1
if [ "$name" = "" ]
then echo -n "Enter a name to search for: "
     read name
fi

grep -i cheryl ~uli101/uli101/phonebook
grep -i $name ~uli101/uli101/phonebook

if [ "$?" != "0" ]
then echo -n "Name '$name' not in directory "
fi
d6kp6zgx

d6kp6zgx1#

在Bash(以及许多其他为UNIX环境开发的编程语言)中,!=运算符表示“不等于”。
在数学符号中,你可以写,但ASCII中不存在这个字符,所以大多数编程语言都采用了另一种方法。(APL只是采用了自己的字符集,所以它可以直接使用,非常感谢。)不同的语言选择不同; Ada和Erlang用/=近似数学符号(Erlang甚至有=/=版本),而BASIC和Pascal使用<>。Fortran通过使用字母作为所有关系运算符来回避整个问题,因此“不等于”是.ne.,而.lt.用于“小于”,.le.用于“小于或等于”,.eq.用于“等于”,.ge..gt.用于“大于或等于”和“大于”。
但是大多数UNIX语言借用了C语言的语法,其中“不相等”的拼写是!=。这不是显而易见的,但它是合乎逻辑的,因为!本身意味着不在同一种语言中。(!0是1,!1是0)。
因此,如果$?不为0,则[ $? != 0 ]为真。什么是$??见下文。)
请注意,这是在进行字符串比较,这可能不是您在这里想要的。如果它是[ $? != 00 ],则条件将始终为真,因为$?永远不会是两个字符串“00”。将表达式放入((中... ))使其以数字方式进行比较:(( $? != 0 ))只有当$?的值(作为数字计算)不为零时才为真,如果您编写(( $? != 00 )),其含义也是一样的。您还可以坚持使用方括号,但更改运算符;要在其中进行数字比较,您需要使用非常类似Fortran拼写的东西:[ $? -ne 0 ]
不管怎样,测试的目的是什么?好吧,特殊的shell参数$?包含上次运行命令时的 * 退出代码 *。从shell运行的每个命令在完成运行时向shell报告一个数字状态;通常,值为0表示命令成功,非零值表示命令失败。(这似乎是落后的,但这个想法是,通常只有一种方法可以成功,但可能有很多方法会出错。同样,只有一个零,但有很多非零的数字,所以一个特定的数字可以提供更多关于发生了什么的信息。
grep命令在文件中搜索与模式匹配的行。如果它找到任何匹配的行,它会将它们打印出来,但如果它找到至少一个匹配,它也会以0(“成功”)状态退出。如果它能够成功地进行搜索,但没有找到任何东西,它将以状态1退出。
因此,在grep之后运行if [ $? != 0 ]就是说“嘿,如果grep没有找到任何东西,那么就这样做。”
但这是一个不必要的迂回的方式做这样的测试。问题是,在bash中传递给if的命令 * 已经是一个要运行的命令 *;如果命令以状态0退出,则执行then块。所以[]方括号只是另一个shell命令,它解释表达式,如果为true,则以状态0退出,如果为false,则以状态1退出。
这意味着这个序列:

somecommand
if (( $? == 0 )); then
  ...
fi

只是写这个等价序列的一个很长的方式:

if somecommand; then
   ...
fi

现在在这个例子中,我们检查的是 not zero而不是zero,但是你可以通过使用!本身来实现同样的结果,它是“not”,就像在C中一样。当它是命令行的开始时,它会翻转命令返回的退出代码的含义:

if ! somecommand; then
   ...
fi

所以OP中的代码可以写得更简洁,像这样:

if ! grep -i "$name" ~uli101/uli101/phonebook; then
  ...
fi

(Note $name周围的双引号;你应该总是用双引号括住参数展开,因为这会阻止shell做像重新拆分单词这样的事情。在本例中,如果没有引号,$name中的空格将把其值转换为grep的多个参数,而不是一个参数;它所查找的模式将在空格处停止,而空格之后的部分将被解释为要查找的第一个文件的名称。

nsc4cvqm

nsc4cvqm2#

[ "$?" != "0" ]表示“$?不等于0”。查看Bash测试操作符here的完整列表。
请注意,如果grep找到匹配,则$?将设置为0,否则1将设置为0。

相关问题