在这里,我在第二个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
2条答案
按热度按时间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退出。这意味着这个序列:
只是写这个等价序列的一个很长的方式:
现在在这个例子中,我们检查的是 not zero而不是zero,但是你可以通过使用
!
本身来实现同样的结果,它是“not”,就像在C中一样。当它是命令行的开始时,它会翻转命令返回的退出代码的含义:所以OP中的代码可以写得更简洁,像这样:
(Note
$name
周围的双引号;你应该总是用双引号括住参数展开,因为这会阻止shell做像重新拆分单词这样的事情。在本例中,如果没有引号,$name
中的空格将把其值转换为grep
的多个参数,而不是一个参数;它所查找的模式将在空格处停止,而空格之后的部分将被解释为要查找的第一个文件的名称。nsc4cvqm2#
[ "$?" != "0" ]
表示“$?
不等于0
”。查看Bash测试操作符here的完整列表。请注意,如果
grep
找到匹配,则$?
将设置为0,否则1
将设置为0。