shell编程if/then备忘

2022-09-23 21:17:35 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

一、基础知识

“[” 是专有命令,而不是普通测试符号(ls /usr/bin/[ 有结果),和test命令等价,并且是内建命令。

bash 2.02 引入 [[…]]扩展测试命令,但是[[是一个关键字,而不是一个命令,Bash把[[ $a -lt $b ]] 看做一个单独的元素,并且返回一个退出状态码

((…))和let …结构也能够返回退出状态吗,当他们所测试的算术表达式的结构为非零的时候,将会返回退出状态码0.

if能偶测试任何命令,并不仅仅是中括号中的条件

代码语言:javascript复制
if cmp a b &>/dev/null
then echo "Files a and b are identical"
else echo "Files a and b diff"
fi
#有用的if-grep结构
if grep -q Bash file
then echo "File contains at least one occurrence of Bash"
fi
word=Linux
letter_sequence=inu
if echo "$word" | grep -q "$letter_sequence" 
#-q 用来禁止输出的
then 
       echo "Found~"
else echo "Not Found!"
fi

test ,/usr/bin/test,[] 和/usr/bin/[都是等价命令

[[ ]]比[ ]更加通用,这是一个扩展的test命令,在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。 使用[[ … ]]条件判断结构, 而不是[ … ], 能够防止脚本中的许多逻辑错误. 比如, &&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错加通用,这是一个扩展的test命令,在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。

二、文件测试操作符

如果下面的条件成立将会返回真. -e 文件存在 -a 文件存在 这个选项的效果与-e相同. 但是它已经被”弃用”了, 并且不鼓励使用. -f 表示这个文件是一个一般文件(并不是目录或者设备文件) -s 文件大小不为零 -d 表示这是一个目录 -b 表示这是一个块设备(软盘, 光驱, 等等.) -c 表示这是一个字符设备(键盘, modem, 声卡, 等等.)

-p 这个文件是一个管道 -h 这是一个符号链接 -L 这是一个符号链接 -S 表示这是一个socket -t 文件(描述符)被关联到一个终端设备上 这个测试选项一般被用来检测脚本中的stdin([ -t 0 ]) 或者stdout([ -t 1 ])是否来自于一个终端. -r 文件是否具有可读权限(指的是正在运行这个测试命令的用户是否具有读权限) -w 文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有写权限) -x文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限) -g set-group-id(sgid)标记被设置到文件或目录上 如果目录具有sgid标记的话, 那么在这个目录下所创建的文件将属于拥有这个目录的用户组, 而不必是创建这个文件的用户组. 这个特性对于在一个工作组中共享目录非常有用. -u set-user-id (suid)标记被设置到文件上 如果一个root用户所拥有的二进制可执行文件设置了set-user-id标记位的话, 那么普通用户也会以root权限来运行这个文件. [1] 这对于需要访问系统硬件的执行程序(比如pppd和cdrecord)非常有用. 如果没有suid标志的话, 这些二进制执行程序是不能够被非root用户调用的. -rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd 对于设置了suid标志的文件, 在它的权限列中将会以s表示. -k 设置粘贴位

对于”粘贴位”的一般了解, save-text-mode标志是一个文件权限的特殊类型. 如果文件设置了这个标志, 那么这个文件将会被保存到缓存中, 这样可以提高访问速度. [2] 粘贴位如果设置在目录中, 那么它将限制写权限. 对于设置了粘贴位的文件或目录, 在它们的权限标记列中将会显示t. drwxrwxrwt 7 root 1024 May 19 21:26 tmp/ 如果用户并不拥有这个设置了粘贴位的目录, 但是他在这个目录下具有写权限, 那么这个用户只能在这个目录下删除自己所拥有的文件. 这将有效的防止用户在一个公共目录中不慎覆盖或者删除别人的文件. 比如说/tmp目录. (当然, 目录的所有者或者root用户可以随意删除或重命名其中的文件.)

-O 判断你是否是文件的拥有者 -G 文件的group-id是否与你的相同

-N 从文件上一次被读取到现在为止, 文件是否被修改过

f1 -nt f2 文件f1比文件f2新

f1 -ot f2 文件f1比文件f2旧

f1 -ef f2 文件f1和文件f2是相同文件的硬链接

! “非” — 反转上边所有测试的结果(如果没给出条件, 那么返回真).

三、其他测试符

二元比较操作符用来比较两个变量或数字. 注意整数比较与字符串比较的区别.

整数比较

-eq

等于 if [ “$a” -eq “$b” ]

-ne

不等于 if [ “$a” -ne “$b” ]

-gt

大于 if [ “$a” -gt “$b” ]

-ge

大于等于 if [ “$a” -ge “$b” ]

-lt 小于 if [ “$a” -lt “$b” ]

-le 小于等于 if [ “a” -le “b” ]

< 小于(在双括号中使用) ((“

<= 小于等于(在双括号中使用) ((“

> 大于(在双括号中使用) ((“$a” > “$b”))

>= 大于等于(在双括号中使用) ((“

字符串比较 = 等于 if [ “a” = “b” ]

== 等于 if [ “a” == “b” ] 与=等价. ==比较操作符在双中括号对和单中括号对中的行为是不同的.

代码语言:javascript复制
  1 [[ $a == z* ]]    # 如果$a以"z"开头(模式匹配)那么结果将为真
  2 [[ $a == "z*" ]]  # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真.
  3 
  4 [ $a == z* ]      # 文件扩展匹配(file globbing)和单词分割有效. 
  5 [ "$a" == "z*" ]  # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真. 
  6 
  7 # 感谢, Stephane Chazelas

!= 不等号 if [ “a” != “b” ]

这个操作符将在[[ … ]]结构中使用模式匹配. < 小于, 按照ASCII字符进行排序

if [[ “a” < “

if [ “a” < “

注意”<“使用在[ ]结构中的时候需要被转义.

> 大于, 按照ASCII字符进行排序 if [[ “a” > “

注意”>”使用在[ ]结构中的时候需要被转义.

参考例子 26-11, 这个例子展示了如何使用这个比较操作符.

-z 字符串为”null”, 意思就是字符串长度为零 -n 字符串不为”null”. 当-n使用在中括号中进行条件测试的时候, 必须要把字符串用双引号引用起来. 如果采用了未引用的字符串来使用! -z, 甚至是在条件测试中括号(参见例子 7-6)中只使用未引用的字符串的话, 一般也是可以工作的, 然而, 这是一种不安全的习惯. 习惯于使用引用的测试字符串才是正路. [1]

四、逻辑与、或

compound comparison-a

逻辑与

exp1 -a exp2 如果表达式exp1和exp2为真的话, 那么结果为真.

-o

逻辑或

exp1 -o exp2 如果表达式exp1和exp2中至少有一个为真的话, 那么结果为真.

这与Bash中的比较操作符&&||非常相像, 但是这个两个操作符是用在双中括号结构中的.

1 [[ condition1 && condition2 ]]

-o-a操作符一般都是和 test命令或者是单中括号结构一起使用的.

1 if [ "$exp1" -a "$exp2" ]

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170871.html原文链接:https://javaforall.cn

0 人点赞