1、算术操作符
2、关系操作符
3、布尔操作符
4、字符串操作符
5、文件相关操作符
算术操作符
bash shell 没有提供任何机制来执行简单的算术运算,不过我们可以借助于一些其他程序,如 expr
#!/bin/sh val=`expr 2 + 2` echo "Total value : $val"
注意:在操作符与表达式之间必须有空格,整个表达式应该用反引号括起来。
其他可用算术操作符:
+:`expr 10 + 20`
-:`expr 10 - 20`
*: `expr 10 * 20` (需要转义乘号)
/: `expr 10 / 2`
%: `expr 10 % 3`
=: (赋值) a = $b,将 b 的值赋予 a
==: [ $a == $b ] 判断两个数是否相等,相等返回 true
!=: [ $a != $b ] 判断两个数是否不想等,不想等返回 true
注意:所有的条件表达式里面的变量、操作符都需要有逗号分隔。至于为什么这样,个人觉得是类似于 $1, $2 ... $n,这种参数获取方式,如果连在一起,可能系统就把这连在一起的两个当作一个操作数什么的。
关系操作符
-eq:判断两个操作对象是否相等,例:[ $a -eq $b ]
-ne:判断两个操作对象是否不想等,例:[ $a -ne $b ]
-gt:判断第一个操作对象是否大于第二个操作对象,例:[ $a -gt $b ]
-lt:判断第一个操作对象是否小于第二个操作对象,例:[ $a -lt $b ]
-ge:[ $a ge $b ],判断 $a 是否大于等于 $b
-le: [ $a le $b ],判断 $a 是否小于等于 $b
逻辑操作符
-a:与,[ $a -lt 20 -a $b -gt 100 ] ,$a 小于 20 且 $b 大于 100 的时候返回 true
-o:或,[ $a -lt 20 -o $b -gt 100 ] ,$a 小于 20 或 $b 大于 100 的时候返回 true
!:非,[ ! false ] 返回 true
字符串比较
=:[ $a = $b ],判断 $a 与 $b 是否相等,注意不是 "=="
!=:[ $a != $b ],判断 $a 与 $b 是否不想等
-z:判断字符串长度是否为0,[ -z $a ],如果 $a 长度为0返回 true
-n:判断字符串长度是否不为0,[ -n $a ],如果 $a 长度不为0返回 true
str:[ $a ],字符串里面如果全是空格,会返回 false," " => false,获取字符串长度的方法:${#str}
暂时不知道 -z 和 -n 的具体用法,上面的 -z 和 -n,在字符串长度不为 0 的时候 -z 也返回了 true。
文件相关判断符
-b:判断文件是不是 block special 文件,硬盘分区是 block special 文件,如:[ -b /dev/disk1s1 ] 会返回 true。
-c:判断文件是不是 character special 文件,[ -c $file ]
-d:判断是不是 目录
-f:判断是不是普通文件,而不是目录或特殊文件
-g:判断文件是否设置了 SGID(Set GID)
-k:判断文件是否设置了 SBIT(Sticky Bit)
-p:判断文件是否是命名管道
-t:判断文件描述符是否是打开状态并且关联了终端
-u:判断文件是否设置了 SUID(Set User ID)
-r:判断文件是否可读
-w:判断文件是否可写
-x:判断文件是否可执行
-s:判断文件的大小是否大于 0
-e:判断文件是否存在
扩展阅读:
1、character special 和 block special 文件类型
When a program reads or writes data from a file, the requests go to a kernel driver. If the file is a regular file, the data is handled by a filesystem driver and it is typically stored in zones on a disk or other storage media, and the data that is read from a file is what was previously written in that place. There are other file types for which different things happen.
When data is read or written to a device file, the request is handled by the driver for that device. Each device file has an associated number which identifies the driver to use. What the device does with the data is its own business.
Block devices (also called block special files) usually behave a lot like ordinary files: they are an array of bytes, and the value that is read at a given location is the value that was last written there. Data from block device can be cached in memory and read back from cache; writes can be buffered. Block devices are normally seekable (i.e. there is a notion of position inside the file which the application can change). The name “block device” comes from the fact that the corresponding hardware typically reads and writes a whole block at a time (e.g. a sector on a hard disk).
Character devices (also called character special files) behave like pipes, serial ports, etc. Writing or reading to them is an immediate action. What the driver does with the data is its own business. Writing a byte to a character device might cause it to be displayed on screen, output on a serial port, converted into a sound, ... Reading a byte from a device might cause the serial port to wait for input, might return a random byte (/dev/urandom
), ... The name “character device” comes from the fact that each character is handled individually.
翻译过来大致是:
块设备(block special) 读写数据的时候是交给设备驱动处理的,怎么处理是设备驱动的事。块设备的数据读写可缓存,块设备读写数据的单位是 block(如:磁盘上的一个扇区)。
字符文件(character special) 读写数据类似于管道,端口;读写是即时处理的;写入这些文件的时候结果可能是显示到屏幕、输出到端口、转换成声音等,从这些文件读取的时候,可能会导致端口等待输入,或者返回一个随机的 byte(/dev/urandom);之所以叫 character special 是因为这些文件一次只会处理单个字符。
2、SGID、SUID、Sticky Bit
SUID
SUID 会出现在文件拥有者权限的执行位上,具有这种权限的文件会在其执行时,使调用者暂时获得该文件拥有者的权限。
如:
ls -l /usr/bin/passwd
结果:
-rwsr-xr-x 1 root root 42824 Sep 13 2012 /usr/bin/passwd
我们可以看到文件拥有者的执行位那里是 s而不是x, 所以说passwd这个程序是具有SUID权限的。我们直到在修改用户密码的时候,用的就是passwd这个命令,而我们又知道在linux下面,用户密码是存储在/etc/shadow这个文件里面的。首先查看一下/etc/shadow这个文件的权限:
ls -l /etc/shadow
结果:
-rw-r----- 1 root shadow 1138 Dec 13 20:00 /etc/shadow
由上面的结果,我们知道只有root可以往shadow文件中写入数据,其他用户连查看的权限都没有。那我们平时是怎么修改密码呢?没错,就是和SUID有关。当我们使用passwd命令时,就获得了passwd的所有者即root的权限,进而可以对shadow文件进行写入操作。使用SUID肯定满足一下几点:
1.SUID只对二进制文件有效
2.调用者对该文件有执行权
3.在执行过程中,调用者会暂时获得该文件的所有者权限
4.该权限只在程序执行的过程中有效
SGID
SGID即Set GID的缩写,它出现在文件所属组权限的执行位上面,它对普通二进制文件和目录都有效。当它作用于普通文件时,和SUID类似,在执行该文件时,用户将获得该文件所属组的权限。当SGID作用于目录时,意义就非常重大了。当用户对某一目录有写和执行权限时,该用户就可以在该目录下建立文件,如果该目录用SGID修饰,则该用户在这个目录下建立的文件都是属于这个目录所属的组。
SBIT
SBIT即Sticky Bit,它出现在其他用户权限的执行位上,它只能用来修饰一个目录。当某一个目录拥有SBIT权限时,则任何一个能够在这个目录下建立文件的用户,该用户在这个目录下所建立的文件,只有该用户自己和root可以删除,其他用户均不可以。例如:
ls -ld /tmp
结果:
drwxrwxrwt 12 root root 12288 Dec 17 16:33 /tmp
可以看到最后一位为t,这说明/tmp文件就是这种文件。
那么,如何设置上面所说的三种权限呢?首先来介绍一点预备的知识,用数字来表示权限:
4表示SUID 2表示SGID 1表示SBIT
如果两个或三个权限同时存在时,就将者写权限的值相加就是需要的结果了。利于SUID和SGID同时存在,则为6。下面可以看一下修改的例子:
chmod 4777 test