没有左边的“如果”,方括号是什么意思?

sup*_*sky 72 shell bash

据我所知,方括号通常用于将表达式括在 if else 语句中。

但我发现方括号没有“if”,如下所示:

[ -r /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh
Run Code Online (Sandbox Code Playgroud)

在下面的脚本中。

#!/bin/bash### BEGIN INIT INFO  
# Provides:          jbossas7  
# Required-Start:    $local_fs $remote_fs $network $syslog  
# Required-Stop:     $local_fs $remote_fs $network $syslog  
# Default-Start:     2 3 4 5  
# Default-Stop:      0 1 6  
# Short-Description: Start/Stop JBoss AS 7  
### END INIT INFO  
# chkconfig: 35 92 1  

## Include some script files in order to set and export environmental variables  
## as well as add the appropriate executables to $PATH.  
[ -r /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh  
[ -r /etc/profile.d/jboss.sh ] && . /etc/profile.d/jboss.sh  

JBOSS_HOME=/sw/AS7  

AS7_OPTS="$AS7_OPTS -Dorg.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0=true"   ## See AS7-1625  
AS7_OPTS="$AS7_OPTS -Djboss.bind.address.management=0.0.0.0"  
AS7_OPTS="$AS7_OPTS -Djboss.bind.address=0.0.0.0"  

case "$1" in  
    start)  
        echo "Starting JBoss AS 7..."  
        #sudo -u jboss sh ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS           ##  If running as user "jboss"  
        #start-stop-daemon --start --quiet --background --chuid jboss --exec ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS   ## Ubuntu  
        ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS &  
    ;;  
    stop)  
        echo "Stopping JBoss AS 7..."  
        #sudo -u jboss sh ${JBOSS_HOME}/bin/jboss-admin.sh --connect command=:shutdown            ##  If running as user "jboss"  
        #start-stop-daemon --start --quiet --background --chuid jboss --exec ${JBOSS_HOME}/bin/jboss-admin.sh -- --connect command=:shutdown     ## Ubuntu  
        ${JBOSS_HOME}/bin/jboss-cli.sh --connect command=:shutdown  
    ;;  
    *)  
        echo "Usage: /etc/init.d/jbossas7 {start|stop}"; exit 1;  
    ;;  
esac  

exit 0  
Run Code Online (Sandbox Code Playgroud)

没有“如果”,方括号有什么作用?我的意思是,确切地说,在这种情况下使用它们是什么意思?

这不是一个重复的,其中OP使用“如果”,我不有一个问题。在这个问题中,括号的使用与直觉相反。这个问题和这个问题可能有相同的答案,但它们是两个不同的问题。

slm*_*slm 87

方括号是执行条件测试的速记符号。括号[以及[[Unix 中的实际命令,信不信由你。

思考:

$ [ -f /etc/rc.local ] && echo "real file"
real file

-and-

$ test -f /etc/rc.local && echo "real file"
real file
Run Code Online (Sandbox Code Playgroud)

在 Bash 中,它[是一个内置命令以及一个可执行文件。[[只是 Bash 的一个关键字。

例子

您可以使用type以下方法确认这一点:

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

$ type -a [[
[[ is a shell keyword
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看物理可执行文件:

$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 37000 Nov  3  2010 /usr/bin/[
Run Code Online (Sandbox Code Playgroud)

内置函数与关键字

如果您查看 Bash 手册页,man bash,您会发现 2 的以下定义:

  • 关键字- 保留字是对 shell 具有特殊含义的字。以下单词在不加引号时被识别为保留字,或者是简单命令的第一个单词(参见下面的 SHELL GRAMMAR)或 case 或 for command 的第三个单词:

    ! case  do done elif else esac fi for function if in select then until while { } time [[ ]]
    
    Run Code Online (Sandbox Code Playgroud)
  • 内置- 如果命令名称不包含斜杠,shell 会尝试定位它。如果存在同名的 shell 函数,则按照上述 FUNCTIONS 中所述调用该函数。如果名称与函数不匹配,shell 将在 shell 内置函数列表中搜索它。如果找到匹配项,则调用该内置函数。

    如果名称既不是 shell 函数也不是内置函数,并且不包含斜杠,则 bash 会在 PATH 的每个元素中搜索包含该名称的可执行文件的目录。Bash 使用哈希表来记住可执行文件的完整路径名(请参阅下面的 SHELL BUILTIN COMMANDS 下的哈希)。只有在哈希表中找不到该命令时,才会对 PATH 中的目录执行完整搜索。如果搜索不成功,shell 将搜索名为 command_not_found_handle 的已定义 shell 函数。如果该函数存在,则使用原始命令和原始命令的参数作为其参数调用它,并且该函数的退出状态成为 shell 的退出状态。如果未定义该函数,shell 会打印一条错误消息并返回退出状态 127。

手册页

如果您浏览 Bash 手册页,您会找到其中的详细信息。

test expr
[ expr ]
          Return a status of 0 or 1 depending on the evaluation of the 
          conditional expression expr.  Each operator and operand must be
          a separate argument.  Expressions are composed of the  primaries 
          described  above  under  CONDITIONAL EXPRESSIONS.   test does not 
          accept any options, nor does it accept and ignore an argument of 
          -- as signifying the end of options.
Run Code Online (Sandbox Code Playgroud)

最后来自手册页:

          test and [ evaluate conditional expressions using a set of rules
          based on the number of arguments.
Run Code Online (Sandbox Code Playgroud)

编辑#1

来自 OP 的后续问题。

好的,那么为什么需要“如果”呢?我的意思是,如果“[”就足够了,为什么“如果”甚至存在。

if是条件的一部分。该test命令或[ ... ]命令只是评估条件,并返回一个0或1。0或1,然后由if语句采取行动。当您使用它们时,这两个是协同工作的。

例子

if [ ... ]; then
   ... do this ...
else 
   ... do that ...
fi
Run Code Online (Sandbox Code Playgroud)

  • @supertonsky - 他们工作但他们只返回测试的状态,他们不能以任何方式对其采取行动。`if` 就像一个开关,并根据条件返回的结果执行或不执行 `then` 块中的命令。`if` 并不是你想象的真正可选的,我们展示的例子使用了 `&&`,有点像 `if`。如果条件失败,则不会运行 `&&` 之后的命令。 (4认同)
  • 好的,那么为什么需要“如果”呢?我的意思是,如果“[”就足够了,为什么“如果”甚至存在。 (2认同)

Mik*_*ehn 34

哦哦,我最喜欢的话题之一!!

方括号是“test”命令的同义词。如果您阅读测试手册页,您将看到您可以调用 test 命令作为

test -r /etc/profile.d/java.sh
Run Code Online (Sandbox Code Playgroud)

或者

[ -r /etc/profile.d/java.sh ]
Run Code Online (Sandbox Code Playgroud)

括号之间的空间和它们内外的东西是必需的。

在这种情况下,“test”命令正在检查文件 /etc/profile.d/java.sh 是否对当前用户可读。当然,隐含是检查它是否存在。:-)

&&是“如果左侧的命令成功,则执行右侧的命令的 bash 语法快捷方式。因此,这个复合命令是“if-then”的简写,如下所示:

if test -r /etc/profile.d/java.sh
then
  /etc/profile.d/java.sh
fi
Run Code Online (Sandbox Code Playgroud)

现在,您还将在 bash 手册页中找到对双方括号的解释。这些是扩展测试功能的 bash 内部版本。请注意,这些并不完全相同。有些事情你可以用“test”命令和它的“[”同义词做不到。