bash测试test详解

bash测试test详解

概述

  • 任何相对完整的计算机语言都能够测试某个条件,然后根据测试的结果采取不同的动作。对于测试条件,
    Bash使用test命令、各种方括号和圆括号、if/then结构等来测试条件。

7.1. Test Constructs

  • 一个if/then语句结构测试一个或多个命令的退出状态是否为0(因为在unix系统中0表示’执行成功’),
    如果为0,就执行语句后面的命令。

  • Bash中有个专用的命令叫[(左中括号,bash特殊字符之一)。它是内置命令test别名,为提升效率
    其同时也是bash的内置命令。该命令视其接受的参数为比较表达式或文件测试(测试文件是否存在、
    文件类型、文件权限等)并且返回一个对应于比较结果的退出状态(如果比较或测试结果为真则返回0,否则返回1)。

  • 在bash2.02版本中,bash新增了[[ … ]]叫扩展的test测试命令,其进行比较时更贴合其他编程语言
    的风格。需要注意的是[[是一个bash关键字而非命令。bash视[[ $a -lt $b ]]为单个元素,返回一个退出状态。

[root@centos8 ~]#type [[
[[ is a shell keyword
[root@centos8 ~]#type [
[ is a shell builtin
[root@centos8 ~]#type test
test is a shell builtin
[root@centos8 ~]#which [
/usr/bin/[
[root@centos8 ~]#which test
/usr/bin/test[root@centos8 ~]#a=3
[root@centos8 ~]#b=4
[root@centos8 ~]#[[ $a -lt $b ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#a=5
[root@centos8 ~]#[[ $a -lt $b ]]
[root@centos8 ~]#echo $?
1
  • ‘(( … ))’ 和 ‘let …’ 结构用来进行简单的数学运算,也会返回一个退出状态,退出状态决定于其里面的
    算术表达式展开后的结果是否是非0值。这些算术运算展开结构可能会被用来进行算术比较。
(( 0 && 1 ))                 # 逻辑与
echo $?     # 1     ***
# And so ...
let "num = (( 0 && 1 ))"
echo $num   # 0
# But ...
let "num = (( 0 && 1 ))"
echo $?     # 1     ***
(( 200 || 11 ))              # 逻辑或
echo $?     # 0     ***
# ...
let "num = (( 200 || 11 ))"
echo $num   # 1
let "num = (( 200 || 11 ))"
echo $?     # 0     ***
(( 200 | 11 ))               # 逐位或
echo $?                      # 0     ***
# ...
let "num = (( 200 | 11 ))"
echo $num                    # 203
let "num = (( 200 | 11 ))"
echo $?                      # 0     ***
# "let" 结构和双圆括号的返回状态相同。
  • “let” 结构和双圆括号的返回状态相同。

  • 注意:某个算术表达式的退出状态不是该算术表达式计算错误的值。

var=-2 && (( var+=2 ))   # 此处算术表达式值为0,退出状态为1
echo $?                   # 1
var=-2 && (( var+=2 )) && echo $var     # 此处由于算术表达式为0,退出状态为1;bash认为非0的退出状态是命令未执行成功,导致$$后面的echo命令不在执行# Will not echo $var!
  • if不仅仅可以测试中括号中的条件,还可以测试任何命令
if cmp a b &> /dev/null  # 压缩标准输出和错误输出.
then echo "Files a and b are identical."
else echo "Files a and b differ."
fi
# The very useful "if-grep" construct:
# ----------------------------------- 
if grep -q Bash filethen echo "File contains at least one occurrence of Bash."
fi
word=Linux
letter_sequence=inu
if echo "$word" | grep -q "$letter_sequence"
# The "-q" option to grep suppresses output.
# -q 选项不输出任何信息到标准输出
thenecho "$letter_sequence found in $word"
elseecho "$letter_sequence not found in $word"
fi
if COMMAND_WHOSE_EXIT_STATUS_IS_0_UNLESS_ERROR_OCCURREDthen echo "Command succeeded."else echo "Command failed."
fi

例7-1. 什么才是真?

#!/bin/bash
#  Tip:
#  如果你不确定某个条件的结果,那最好在if测试结构中测试其。
echo
echo "Testing \"0\""
if [ 0 ]      # zero
thenecho "0 is true."
else          # Or else ...echo "0 is false."
fi            # 0 为真.
echo
echo "Testing \"1\""
if [ 1 ]      # one
thenecho "1 is true."
elseecho "1 is false."
fi            # 1 为真.
echo
echo "Testing \"-1\""
if [ -1 ]     # -1
thenecho "-1 is true."
elseecho "-1 is false."
fi            # -1 为真.
echo
echo "Testing \"NULL\""
if [ ]        # NULL (空条件)
thenecho "NULL is true."
elseecho "NULL is false."
fi            # NULL 空为假。
echo
echo "Testing \"xyz\""
if [ xyz ]    # 随机字符串
thenecho "Random string is true."
elseecho "Random string is false."
fi            # 随机字符串为真.
echo
echo "Testing \"\$xyz\""
if [ $xyz ]   # 测试变量$xyz是否为空, 但是...# $xyz只是一个未初始化的变量.
thenecho "Uninitialized variable is true."
elseecho "Uninitialized variable is false."
fi            # 未初始化的字符串为假.
echo
echo "Testing \"-n \$xyz\""
if [ -n "$xyz" ]            # 有点卖弄学问的做法.
thenecho "Uninitialized variable is true."
elseecho "Uninitialized variable is false."
fi            # 同样未初始化的字符串为假.
echo
xyz=          # 初始化了,但是值为空.
echo "Testing \"-n \$xyz\""
if [ -n "$xyz" ]
thenecho "Null variable is true."
elseecho "Null variable is false."
fi            # 空变量为假.
echo
# 什么时候'假'为真呢?(When is "false" true?)
echo "Testing \"false\""
if [ "false" ]              # 此处 "false" 只是一个字符串而已...
thenecho "\"false\" is true." #+ 结果为真啦啦啦.
elseecho "\"false\" is false."
fi            # 这时候'假'为真.
echo
echo "Testing \"\$false\""  # 再次测试'假',此时的'假'为未初始化的变量.
if [ "$false" ]
thenecho "\"\$false\" is true."
elseecho "\"\$false\" is false."
fi            # 此时测试结构为假.
#  What would happen if we tested the uninitialized variable "$true"?
echo
exit 0
if [ condition-true ]
thencommand 1command 2...
else  # 或者Or else ...# 在下面写测试条件为假时的代码.command 3command 4...
fi
  • 条件测试结构中当if和then在同一行时,必须使用分号结束if语句。if和then都为bash关键字。
      关键字(或者命令)所开始的语句,必须在同一行的下一个语句前使用分号结束。
if [ -x "$filename" ]; then
  • Else if and elif
  • elif 是 else if 的简写.用来实现嵌套语句.
if [ condition1 ]
thencommand1command2command3
elif [ condition2 ]
# Same as else if
thencommand4command5
elsedefault-command
fi
  • 结构’if test condition-true’和结构’if [ condition-true ]‘完全等价。当使用后者时,左中括号’['会调用test命令。
    所以右中括号在if/test结构中不是严格需要的,然而新版本的bash要求必须跟上。
  • 特别指出:test命令时bash内置命令。其用来测试文件类型和比较字符串。因此,
    在bash脚本中test命令不会调用外部二进制命令/usr/bin/test,此时的test命令是sh-utils包的一部分。
bash$ type test
test is a shell builtin
bash$ type '['
[ is a shell builtin
bash$ type '[['
[[ is a shell keyword
bash$ type ']]'
]] is a shell keyword
bash$ type ']'
bash: type: ]: not found
  • 如果由于某些原因,你希望在脚本中使用/usr/bin/test,那可以使用完整的路径名指明.

例7-2.test,/usr/bin/test,[ ],和/usr/bin/[

#!/bin/bash
echo
if test -z "$1"
thenecho "No command-line arguments."
elseecho "First command-line argument is $1."fi
echo
if /usr/bin/test -z "$1"      # 和内置命令"test"等价.
#  ^^^^^^^^^^^^^              # 指明了完整的路径.
thenecho "No command-line arguments."
elseecho "First command-line argument is $1."
fi
echo
if [ -z "$1" ]                # 和上面的代码块功能相同.
#   if [ -z "$1"              # 该代码应该可以正常工作,但是...
#+  Bash说后面的右中括号必须带,哎.
thenecho "No command-line arguments."
elseecho "First command-line argument is $1."
fi
echo
if /usr/bin/[ -z "$1" ]       # 和上面的代码块功能相同.
thenecho "No command-line arguments."
elseecho "First command-line argument is $1."
fi
echo
exit 0
  • 相比’[ ]‘,’[[ ]]'测试结构更加健壮。后者是扩展的test命令,从ksh88版本中借鉴而来。
  • 在’[[ ]]’ 结构中不允许文件名展开或者单词分割,但是允许参数展开和命令替换。
file=/etc/passwd
if [[ -e $file ]]
thenecho "Password file exists."
fi
  • 使用’[[ … ]]‘测试结构,而不使用’[ … ]‘可以避免脚本中很多逻辑错误。
    比如:&&,||,<,>操作符在’[[ ]]‘结构中适用,但是在’[ ]'结构中报错。
  • 对于八进制/十六进制的算术运算在’[[ ]]'结构中亦支持。
# [[ 八进制/十六进制运算 ]]
# Thank you, Moritz Gronbach, for pointing this out.
decimal=15
octal=017   # = 15 (decimal)
hex=0x0f    # = 15 (decimal)
if [ "$decimal" -eq "$octal" ]
thenecho "$decimal equals $octal"
elseecho "$decimal is not equal to $octal"       # 结果是15不等于017
fi      # 在单中括号结构中不计算 [ single brackets ]!
if [[ "$decimal" -eq "$octal" ]]
thenecho "$decimal equals $octal"                # 15 等于 017
elseecho "$decimal is not equal to $octal"
fi      # 双中括号中计算 [[ double brackets ]]!
if [[ "$decimal" -eq "$hex" ]]
thenecho "$decimal equals $hex"                  # 15 等于 0x0f
elseecho "$decimal is not equal to $hex"
fi      # [[ $hexadecimal ]] 单独引用一个十六进制数,也会自动计算为十进制!
  • 在if后,要么test命令要么测试中括号都是必须存在的([] [[ ]])。
dir=/home/bozo
if cd "$dir" 2>/dev/null; then   # "2>/dev/null"将会重定向标准错误.echo "Now in $dir."
elseecho "Can't change to $dir."
fi
  • 如上面例子,"if 命令"结构会返回命令的退出状态。
  • 同样,下面在多个结构的组合用法中,一个处于中括号内的测试条件可以不需要if。
var1=20
var2=22
[ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2"
home=/home/bozo
[ -d "$home" ] || echo "$home directory does not exist."
  • 双圆括号结构(( ))展开并计算数学运算表达式。如果表达式运算结果为0,则其返回一个为1的退出状态,或者假"false"。一个非0的计算值则返回一个退出状态0,或者真"true"。

例7-3.使用(( ))结构测试算术运算结果

#!/bin/bash
# arith-tests.sh
# Arithmetic tests.
# (( ... ))结构计算并测试数学运算表达
# (( ... ))结构对于数学运算表达式的测试结果退出状态与[ ... ]结构相反!
# (( ... ))结构中运算结果非0为真,运算结果为0时退出状态为假。
(( 0 ))
echo "Exit status of \"(( 0 ))\" is $?."         # 1
(( 1 ))
echo "Exit status of \"(( 1 ))\" is $?."         # 0
(( 5 > 4 ))                                      # true
echo "Exit status of \"(( 5 > 4 ))\" is $?."     # 0
(( 5 > 9 ))                                      # false
echo "Exit status of \"(( 5 > 9 ))\" is $?."     # 1
(( 5 == 5 ))                                     # true
echo "Exit status of \"(( 5 == 5 ))\" is $?."    # 0
# (( 5 = 5 ))  gives an error message.
(( 5 - 5 ))                                      # 0
echo "Exit status of \"(( 5 - 5 ))\" is $?."     # 1
(( 5 / 4 ))                                      # Division o.k.
echo "Exit status of \"(( 5 / 4 ))\" is $?."     # 0
(( 1 / 2 ))                                      # 除法结果小于1.
echo "Exit status of \"(( 1 / 2 ))\" is $?."     # 小于1的结果被圆整为0.# 1
(( 1 / 0 )) 2>/dev/null                          # 使用0作为除数非法.
#           ^^^^^^^^^^^
echo "Exit status of \"(( 1 / 0 ))\" is $?."     # 1
# ======================================= #
# (( ... )) 该结构也常常被用在 if-then 测试结构中.
var1=5
var2=4
if (( var1 > var2 ))
then #^      ^      Note: Not $var1, $var2. Why?echo "$var1 is greater than $var2"
fi     # 5 is greater than 4
exit 0

7.2. 文件测试操作(File test operators)

  • if [ … ] 如果测试条件…为真则返回退出状态值0

-e 测试文件是否存在
-a 同上,已经被弃用,不推荐使用
-f 测试文件是否为普通文件(不是文件夹或者设备文件)
-s 测试文件是否非空(大小不是0)
-d 测试文件是否是一个文件夹
-b 测试文件是否是一个块设备
-c 测试文件是否是一个字符设备

device0="/dev/sda2"
if [ -b "$device0" ]
thenecho "$device0 is a block device."
fi
# /dev/sda2 是一个块设备.device1="/dev/ttyS1"  
if [ -c "$device1" ]
thenecho "$device1 is a character device."
fi
# /dev/ttyS1 是一个字符设备.

-p 测试文件是否为管道文件.

function show_input_type()
{[ -p /dev/fd/0 ] && echo PIPE || echo STDIN    # 此处/dev/fd/0表示标准输入
}
show_input_type "Input"                           # STDIN 标准输入
echo "Input" | show_input_type                    # PIPE  管道

-h 测试文件是否是一个符号链接
-L 测试文件是否是一个符号
-S 测试文件是否是一个socket文
-t 测试文件(或者文件描述符)是否与某个终端关联
  该测试可以测试脚本中的标准输入[ -t 0 ]或者标准输出[ -t 1 ]是否是一个终端。
-r 运行本测试的用户是否对文件有读权限
-w 写权限
-x 执行权限
-g 文件或者文件夹是否设置SGID标志位
  如果某个文件或者文件夹上设置有SGID权限,那么在该文件夹下创建的文件属主为该文件夹的属主。
-u 文件或者文件夹是否设置suid
  如果某个属于root的二进制文件上被root设置了SUID标志位,则不管是谁运行,该可执行文件都以root权限运行;
  单某个可执行文件必须要访问系统硬件时此功能非常有用。如果缺失SUID标志位,这些二进制文件不能被非root用户运行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7NmYZ4x-1691108945997)(png/2019-10-21-12-40-31.png)]

  如上图:有SUID标志位的文件权限模式的执行权限位标识为s而不再是x(rwx --> rws).

-k 测试sticky位是否设置
  如果一个文件设置了sticky位,那么该问价会被保存在cache内便于访问
  如果某个文件夹被设置了sticky位,那么该文件夹的写权限将会被限制。
  设置sticky位后,其他用户的执行权限模式不在表现为x而是t(rwx --> rwt)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLENSzNn-1691108945998)(png/2019-10-21-12-56-29.png)]
  也就是说:如果一个用户对某个设置有sticky位的目录有读权限但不是该目录的属主,那么他只能删除该目录下其拥有
  的文件。这样做可以防止用户在公共文件夹意外删除别人的文件,例如/tmp文件夹。(当然,root用户是可以删除和更改的)
-O 测试自己是否是文件属主
-G 测试文件的GID是否和自己相同
-N 测试文件自最后一次读以来是否被修改过
f1 -nt f2 测试文件f1是否是比f2新
f1 -ot f2 测试文件f1是否是比f2旧
f1 -ef f2 测试文件f1和f2是否都是同一个文件的硬链接
! 对上面所列的条件取反。(如果条件为空,返回真,如下面例子)

[root@centos8 ~]#if [[ ! ]]; then echo true; fi
true

例7-4. 测试失效的链接(Testing for broken links)

#!/bin/bash
# broken-link.sh
# Written by Lee bigelow <ligelowbee@yahoo.com>
# Used in ABS Guide with permission.
#  该脚本找出失效的符号链接并引用后输出。以便于给xargs处理。
#+ 例如. sh broken-link.sh /somedir /someotherdir|xargs rm
#  只不过更加推荐下面的方法:
#  find "somedir" -type l -print0|\
#  xargs -r0 file|\
#  grep "broken symbolic"|
#  sed -e 's/^\|: *broken symbolic.*$/"/g'
#
#  注意: 谨慎对待 /proc 文件系统和任何循环链接
################################################################
#  下面的语句表示如果没有指定目录参数传给脚本就将路径设置为当前的工作
#  目录。否则使用指定的目录参数进行搜索。
######################
[ $# -eq 0 ] && directorys=`pwd` || directorys=$@#  下面的函数检查传给脚本的目录中为符号链接并且不存在的文件,检查到后引用起来并打印。
#  如果是目录中的子目录,则将该目录再次传给函数检查。
##########
linkchk () {for element in $1/*; do[ -h "$element" -a ! -e "$element" ] && echo \"$element\"[ -d "$element" ] && linkchk $element# Of course, '-h' tests for symbolic link, '-d' for directory.done
}#  下面将每个传给脚本的合法目录参数传给linkchk()函数,如果不是合法目录,则打印错误信息和用法。
##################
for directory in $directorys; doif [ -d $directory ]then linkchk $directoryelseecho "$directory is not a directory"echo "Usage: $0 dir1 dir2 ..."fi
done
exit $?

7.3. 其它的比较操作

  • 一个二进制比较操作符号比较两个变量或者比较数量。整数或者字符串的比较使用特定的符号集合。

  • 整数比较

-eq 是否相等
if [ "$a" -eq "$b" ]-ne 是否不等
if [ "$a" -ne "$b" ]-gt $a是否大于$b
if [ "$a" -gt "$b" ]-ge $a是否大于或等于$b
if [ "$a" -ge "$b" ]-lt $a是否小于$b
if [ "$a" -lt "$b" ]-le $a是否小于或等于$b
if [ "$a" -le "$b" ]< 小于(必须在双圆括号结构中)
(("$a" < "$b"))<= 小于或等于(必须在双圆括号结构中)
(("$a" <= "$b"))> 大于(必须在双圆括号结构中)
(("$a" > "$b"))>= 大于或等于(必须在双圆括号结构中)
(("$a" >= "$b"))
  • 字符串比较
= is equal to
if [ "$a" = "$b" ]注意=两边的空格.
if [ "$a"="$b" ] # 注意:该写法与上面的不等价.
== is equal to
if [ "$a" == "$b" ]
该写法是 = 的近似写法.
[[ $a == z* ]]   # 如果 $a 以字母"z"开头则为真(模式匹配).
[[ $a == "z*" ]] # 将"z*"视为普通字符串.
[ $a == z* ]     # 此处会视为通配和单词分割.
[ "$a" == "z*" ] # 将"z*"视为普通字符串.
# Thanks, Stéphane Chazelas
!= 是否不等
if [ "$a" != "$b" ]
该操作符也可以在[[ ... ]]结构中参与模式匹配操作.
< 是否小于,以ASCII字符的顺序比较
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
注意: "<"[ ] 结构中需要被转义.
> 是否大于,以ASCII字符的顺序比较
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]

-z 判断某字符串是否为空,也就是长度为0

String=''   # Zero-length ("null") string variable.
if [ -z "$String" ]
thenecho "\$String is null."
elseecho "\$String is NOT null."
fi     # $String is null.

-n 判断某字符串是否非空.

  • 注意:-n 测试选项需要被测试的字符串被双引号引用起来,一般总是将被测试的字符串引用起来。

例 7-5. 算术运算和比较

#!/bin/bash
a=4
b=5
#  Here "a" and "b" can be treated either as integers or strings.
#  There is some blurring between the arithmetic and string comparisons,
#+ since Bash variables are not strongly typed.
#  Bash permits integer operations and comparisons on variables
#+ whose value consists of all-integer characters.
#  Caution advised, however.
echo
if [ "$a" -ne "$b" ]  # 数学运算比较
thenecho "$a is not equal to $b"echo "(arithmetic comparison)"
fi
echo
if [ "$a" != "$b" ]   # 字符串比较
thenecho "$a is not equal to $b."echo "(string comparison)"#     "4"  != "5"# ASCII 52 != ASCII 53
fi
# 在该例子中 "-ne" 和 "!=" 都可以.
echo
exit 0

例 7-6. 测试某字符串是否为空

#!/bin/bash
#  str-test.sh: Testing null strings and unquoted strings,
#+ but not strings and sealing wax, not to mention cabbages and kings . . .
# Using   if [ ... ]
# If a string has not been initialized, it has no defined value.
# 如果一个字符串没有被定义,其没有被定义的值,这种状态叫'null'
if [ -n $string1 ]    # string1 没有被初始化或定义过.
thenecho "String \"string1\" is not null."
else  echo "String \"string1\" is null."
fi
# 此处认为$string1非空,即使它没有被初始化.
echo
# 再试试?
if [ -n "$string1" ]  # 这次 $string1 被双引号引用起来.
thenecho "String \"string1\" is not null."
else  echo "String \"string1\" is null."
fi                    # 为空!
echo
if [ $string1 ]       # 此处变量string未引起
thenecho "String \"string1\" is not null."
else  echo "String \"string1\" is null."
fi                    # 为空,正确.
# 最好还是引用起来需要测试的字符串,不管是变量还是字符串本身.
#
# As Stephane Chazelas points out,
#    if [ $string1 ]    has one argument, "]"#该测试结果只有一个参数"]"
#    if [ "$string1" ]  has two arguments, the empty "$string1" and "]"#该测试结果有两个参数空字符串"$string1"和"]"
echo
string1=initialized
if [ $string1 ]       # 赋值后, $string1 .
thenecho "String \"string1\" is not null."
else  echo "String \"string1\" is null."
fi                    # 非空.
# 然而,最好还是引起来,因为...
string1="a = b"
if [ $string1 ]
thenecho "String \"string1\" is not null."
else  echo "String \"string1\" is null."
fi                    # 此处不引用导致错误!
exit 0   # Thank you, also, Florian Wisser, for the "heads-up".

例 7-7. zmore

#!/bin/bash
# zmore
# View gzipped files with 'more' filter.
E_NOARGS=85
E_NOTFOUND=86
E_NOTGZIP=87
if [ $# -eq 0 ] # same effect as:  if [ -z "$1" ]
# $1 can exist, but be empty:  zmore "" arg2 arg3
thenecho "Usage: `basename $0` filename" >&2# Error message to stderr.exit $E_NOARGS# Returns 85 as exit status of script (error code).
fi  
filename=$1
if [ ! -f "$filename" ]   # 使用引号可以避免带空格的文件名出错.
thenecho "File $filename not found!" >&2   # Error message to stderr.exit $E_NOTFOUND
fi  
if [ ${filename##*.} != "gz" ]
# Using bracket in variable substitution.
thenecho "File $1 is not a gzipped file!"exit $E_NOTGZIP
fi  
zcat $1 | more
# Uses the 'more' filter.
# May substitute 'less' if desired.
exit $?   # Script returns exit status of pipe.
#  Actually "exit $?" is unnecessary, as the script will, in any case,
#+ return the exit status of the last command executed.
  • compound comparison

-a
logical and
exp1 -a exp2 returns true if both exp1 and exp2 are true.
-o
logical or
exp1 -o exp2 returns true if either exp1 or exp2 is true.

  • These are similar to the Bash comparison operators && and ||, used within double brackets.
[[ condition1 && condition2 ]]
  • The -o and -a operators work with the test command or occur within single test brackets.
if [ "$expr1" -a "$expr2" ]
thenecho "Both expr1 and expr2 are true."
elseecho "Either expr1 or expr2 is false."
fi
  • But, as rihad points out:
[ 1 -eq 1 ] && [ -n "ècho true 1>&2`" ]   # true
[ 1 -eq 2 ] && [ -n "ècho true 1>&2`" ]   # (no output)
# ^^^^^^^ False condition. So far, everything as expected.
# However ...
[ 1 -eq 2 -a -n "ècho true 1>&2`" ]       # true
# ^^^^^^^ False condition. So, why "true" output?
# Is it because both condition clauses within brackets evaluate?
[[ 1 -eq 2 && -n "ècho true 1>&2`" ]]     # (no output)
# No, that's not it.
# Apparently && and || "short-circuit" while -a and -o do not.

7.4. Nested if/then Condition Tests

  • Condition tests using the if/then construct may be nested. The net result is equivalent to using the &&
    compound comparison operator.
a=3
if [ "$a" -gt 0 ]
thenif [ "$a" -lt 5 ]thenecho "The value of \"a\" lies somewhere between 0 and 5."fi
fi
# Same result as:
if [ "$a" -gt 0 ] && [ "$a" -lt 5 ]
thenecho "The value of \"a\" lies somewhere between 0 and 5."
fi

7.5. Testing Your Knowledge of Tests

  • The systemwide xinitrc file can be used to launch the X server. This file contains quite a number of if/then
    tests. The following is excerpted from an “ancient” version of xinitrc (Red Hat 7.1, or thereabouts).
if [ -f $HOME/.Xclients ]; thenexec $HOME/.Xclients
elif [ -f /etc/X11/xinit/Xclients ]; thenexec /etc/X11/xinit/Xclients
else# failsafe settings.  Although we should never get here# (we provide fallbacks in Xclients as well) it can't hurt.xclock -geometry 100x100-5+5 &xterm -geometry 80x50-50+150 &if [ -f /usr/bin/netscape -a -f /usr/share/doc/HTML/index.html ]; thennetscape /usr/share/doc/HTML/index.html &fi
fi
  • Explain the test constructs in the above snippet, then examine an updated version of the file,
    /etc/X11/xinit/xinitrc, and analyze the if/then test constructs there. You may need to refer ahead to
    the discussions of grep, sed, and regular expressions.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/22539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swish - Mac 触控板手势窗口管理工具[macOS]

Swish for Mac是一款Mac触控板增强工具&#xff0c;借助直观的两指轻扫&#xff0c;捏合&#xff0c;轻击和按住手势&#xff0c;就可以从触控板上控制窗口和应用程序。 Swish for Mac又不仅仅只是一个窗口管理器&#xff0c;Swish具有28个易于使用的标题栏&#xff0c;停靠栏…

PHP Thinkphp5.0实现抖音团购券码核销

上一篇文章我们说到项目里需要用到美团API接口来实现卡券核销的功能。 那么这篇文章就讲一下&#xff0c;如何实现抖音团购券码的核销功能。 近期项目需要&#xff0c;抖音团购的券码核销&#xff0c;话不多说&#xff0c;直接上代码吧&#xff01; 凑合着用吧&#xff0c;反正…

pytorch的CrossEntropyLoss交叉熵损失函数默认是平均值

pytorch中使用nn.CrossEntropyLoss()创建出来的交叉熵损失函数计算损失默认是求平均值的&#xff0c;即多个样本输入后获取的是一个均值标量&#xff0c;而不是样本大小的向量。 net nn.Linear(4, 2) loss nn.CrossEntropyLoss() X torch.rand(10, 4) y torch.ones(10, dt…

MySQL表的内外连接

MySQL表的内外连接 一.内连接二.外连接1. 左外连接2. 右外连接 三.案例 表的连接分为内连和外连。 一.内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选&#xff0c;我们前面学习的查询都是内连接&#xff0c;也是在开发过程中使用的最多的连接查询。而使…

DBA 职责及日常工作职责

DBA 职责及日常工作职责: 1.安装和升级数据库服务器,以及应用程序工具构建和配置网络环境. 2.熟悉数据库系统的存储结构预测未来的存储需求,制订数据库的存储方案. 3.根据开发人员设计的应用系统需求创建数据库存储结构. 4.根据开发人员设计的应用系统需求创建数据库对象 5…

刷题DAY15

第一题 给定一个数组arr 求子数组最大累加和 最暴力的 枚举每一个子数组 出结果 优化解 用一个cur指针保存累加和 每次cur变大 就用它更新max 如果cur累加到0以下 回复成0 假设答案法 假设我们最大的子数组是i 到 j位置上的 那么这个i 到j 之间 必不存在一个k使i...k累加和…

网络面试题-UDPTCP

1 UDP 1.1 ⾯向报⽂ UDP 是⼀个⾯向报⽂&#xff08;报⽂可以理解为⼀段段的数据&#xff09;的协议。意思就是UDP 只是报⽂的搬运⼯&#xff0c;不会对报⽂进⾏任何拆分和拼接操作 具体来说 在发送端&#xff0c;应⽤层将数据传递给传输层的 UDP 协议&#xff0c; UDP 只会…

Aligning Large Language Models with Human: A Survey

本文也是LLM相关的综述文章&#xff0c;针对《Aligning Large Language Models with Human: A Survey》的翻译。 对齐人类与大语言模型&#xff1a;综述 摘要1 引言2 对齐数据收集2.1 来自人类的指令2.1.1 NLP基准2.1.2 人工构造指令 2.2 来自强大LLM的指令2.2.1 自指令2.2.2 …

sql分类 DDL、DML、DCL

DDL &#xff08;Data Definition Language 数据定义语言) 这些语句定了不同的数据库、表、视图、索引等数据库对象&#xff0c;还可以用来创建、删除、修改数据库和数据表的结构 如: CREATE \ DROP \ ALTER \ RENAME \ TRUNCATE 等 DML&#xff08;Data Manipulation Langua…

前端面试的性能优化部分(3)每天10个小知识点

31.请解释前端性能优化的重要性以及优化的目标是什么&#xff1f; 前端性能优化是指在网页或应用的前端部分&#xff08;通常是指用户界面&#xff09;进行改进&#xff0c;以提高其加载速度、响应性能和用户体验。在现代互联网应用中&#xff0c;前端性能优化至关重要&#x…

antDv table组件滚动截图方法的实现

在开发中经常遇到table内容过多产生滚动的场景&#xff0c;正常情况下不产生滚动进行截图就很好实现&#xff0c;一旦产生滚动就会变得有点棘手。 下面分两种场景阐述解决的方法过程 场景一&#xff1a;右侧不固定列的情况 场景二&#xff1a;右侧固定列的情况 场景一 打开…

汽车电子功能安全

功能安全考虑 分析方法&#xff1a;FMEA&#xff0c;DFMEA&#xff08;设计潜在失效模式和影响分析&#xff09; 严重度&#xff08;Severity&#xff09;&#xff0c;暴露率&#xff08;Exposure&#xff09;&#xff0c;可控性&#xff08;Controllability&#xff09;评估…

IDEA中maven项目失效,pom.xml文件橙色/橘色

IDEA中maven项目失效&#xff0c;pom.xml文件橙色/橘色 IDEA中Maven项目失效 IDEA中创建的maven项目中的文件夹都变成普通格式&#xff0c;pom.xml变成橙色 右键点击橙色的pom.xml文件&#xff0c;选择add as maven project maven项目开始重新导入相应依赖&#xff0c;恢复…

JavaScript |(四)正则表达式 | 尚硅谷JavaScript基础实战

学习来源&#xff1a;尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 文章目录 &#x1f4da;正则表达式&#x1f4da;正则表达式字面量方式&#x1f4da;字符串&正则表达式&#x1f407;split()&#x1f407;search()&#x1f407;match()&#x1f407;replace()…

MyBatis-动态SQL-if and where

动态SQL 随着用户的输入或外部条件的变化而变化的SQL语句&#xff0c;我们称之为动态SQL语句 select *from empwhere name like concat(%, #{name}, %)and gender #{gender}and entrydate between #{begin} and #{end}order by update_time desc; 在上述的SQL语句…

如何实现 token 加密

介绍下如何实现 token 加密 以最常见的 token 格式 jwt 为例 token 分为三段&#xff0c;分别是 header、payload、signature 其中&#xff0c;header 标识签名算法和令牌类型&#xff1b;payload 标识主体信息&#xff0c;包含令牌过期时间、发布时间、发行者、主体内容等&…

科技引领,教育革新|EasyV助力数字孪生智慧教育建设!

数字孪生校园是以物联网、大数据、云计算、人工智能、三维可视化等新型数字化技术为基础&#xff0c;构建的数智校园的“大脑”。对校园的人、车、资产设施、各业务系统进行全联接&#xff0c;实现数据全融合、状态全可视、业务全可管、事件全可控&#xff0c;使校园更安全、更…

2023-08-04 LeetCode每日一题(不同路径 III)

2023-08-04每日一题 一、题目编号 980. 不同路径 III二、题目链接 点击跳转到题目位置 三、题目描述 在二维网格 grid 上&#xff0c;有 4 种类型的方格&#xff1a; 1 表示起始方格。且只有一个起始方格。2 表示结束方格&#xff0c;且只有一个结束方格。0 表示我们可以…

985/211/双一流大学名单

985大学“985工程”是在1998年5月北京大学百年校庆的致辞中提到的&#xff0c;因为日期在98年5月&#xff0c;所以称作“985”。该工程在1999年时正式启动&#xff0c;最初选定的院校包括清华大学&#xff0c;北京大学等九所院校。现包括我国39所院校。 211大学“211 工程”是…

Noah-MP陆面过程模型建模方法与站点、区域模拟教程

详情点击链接&#xff1a;Noah-MP陆面过程模型建模方法与站点、区域模拟教程 陆面过程的内容&#xff08;陆表能量平衡、水循环、碳循环等&#xff09;&#xff0c;陆面过程研究的重要性。 图 1 陆面过程主要研究内容 陆面过程模型的发展、基本原理、常用陆面过程模型等。 图…