基础知识
条件判断
测试选项 |
作用 |
-b 文件 |
判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) |
-c 文件 |
判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真) |
-d 文件 |
判断该文件是否存在,并且是否为目录(是目录为真) |
-e 文件 |
判断该文件是否存在(存在为真) |
-f 文件 |
判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 |
判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真) |
-p 文件 |
判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-s 文件 |
判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 |
判断该文件是否存在,并且是否为套接字文件(是套接字文件为真) |
测试选项 |
作用 |
-r 文件 |
判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真) |
-w 文件 |
判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真) |
-x 文件 |
判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真) |
-u 文件 |
判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真) |
-g 文件 |
判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真) |
-h 文件 |
判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真) |
测试选项 |
作用 |
A -nt B |
判断A的修改时间是否比B的新(如果新则为真) |
A -ot B |
判断A的修改时间是否比B的旧(如果旧则为真) |
A -ef B |
判断A和B的inode号是否一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
测试选项 |
作用 |
A -eq B |
判断A和B是否相等(相等为真) |
A -ne B |
判断A和B是否不相等(不相等为真) |
A -gt B |
判断A是否大于B(大于为真) |
A -lt B |
判断A是否小于B(小于为真) |
A -ge B |
判断A是否大于等于B(大于等于为真) |
A -le B |
判断A是否小于等于B(小于等于为真) |
测试选项 |
作用 |
-z 字符串 |
判断字符串是否为空(为空返回真) |
-n 字符串 |
判断字符串是否非空(非空返回真) |
A == B |
判断A和B是否相等(相等返回真) |
A != B |
判断A和B是否不相等(不相等返回真) |
测试选项 |
作用 |
A -a B |
逻辑与,A和B都成立,最终的结果才为真 |
[ A ] and [B] |
逻辑与,A和B都成立,最终的结果才为真 |
A -o B |
逻辑或,A或B有一个成立,最终的结果就为真 |
[ A ] or [B] |
逻辑或,A或B有一个成立,最终的结果就为真 |
! A |
逻辑非,是原始的判断式取反 |
基本语法
### 方式一
if [ 条件 ]; then
命令
fi
if [ 条件 ] && [ 条件 ]; then
命令
fi
if [ 条件 ]
then
命令
fi
### 方式二
if [ 条件 ]; then
命令
else
命令
fi
if [ 条件 ]
then
命令
else
命令
fi
### 方式三
if [ 条件 ]; then
命令
elif [ 条件 ]; then
命令
else
命令
fi
if [ 条件 ]
then
命令
elif [ 条件 ]
then
命令
else
命令
fi
case $VAL in
"A")
命令
;;
"B")
命令
;;
*)
命令
;;
esac
for VAL in $VAL;do
命令
done
for VAL in $VAL
do
命令
done
while [ 条件 ];do
命令
done
while [ 条件 ]
do
命令
done
until [ 条件 ];do
命令
done
until [ 条件 ]
do
命令
done
语法样例
### case样例
#!/bin/sh
for VAL in 1 2 3; do
echo "VAL is $VAL"
case $VAL in
1)
echo "1"
;;
2)
echo "2"
;;
*)
echo "*"
;;
esac
done
### for样例
#!/bin/sh
for VAL in 3 4; do
echo "A VAL is $VAL"
done
for VAL in 5 6
do
echo "A VAL is $VAL"
done
### while样例
#!/bin/sh
VAL=7
while [ $VAL -gt 5 ]; do
echo "A VAL is $VAL"
VAL=$[VAL - 1]
done
while [ $VAL -gt 3 ]
do
echo "B VAL is $VAL"
VAL=$[VAL - 1]
done
### until样例
#!/bin/sh
VAL=7
until [ $VAL -lt 5 ]; do
echo "A VAL is $VAL"
VAL=$[VAL - 1]
done
until [ $VAL -lt 3 ]
do
echo "B VAL is $VAL"
VAL=$[VAL - 1]
done
字符串高级操作
样例变量VAL=http://news.163.com/index.html
#
号截取,删除左边字符,保留右边字符(非贪婪匹配)
### *//表示从左边开始删除第一个//及其左边的字符(*),结果为:news.163.com/index.html
echo ${VAL#*//}
### */表示从左边开始删除最后一个/(最右边)及其左边的字符(*),结果为:index.html
echo ${VAL##*/}
%
号截取,删除右边字符,保留左边字符(非贪婪匹配)
### /*表示从右边开始,删除第一个/及其右边的字符(*),结果为:http://news.163.com
echo ${VAL%/*}
%%
号截取,删除右边字符,保留左边字符(贪婪匹配)
### /*表示从右边开始,删除最后一个/(最左边)及其右边的字符(*),结果为:http:
echo ${VAL%%/*}
### 0表示从左边的第1个字符开始的4个字符,结果为:http
echo ${VAL:0:4}
### 7表示从左边的第8个字符开始直到结束,结果为:news.163.com/index.html
echo ${VAL:7}
### 0-10表示从右边的第10个字符开始的5个字符,结果为:index
echo ${VAL:0-10:5}
### 0-10表示从右边的第10个字符开始直到结束,结果为:index.html
echo ${VAL:0-10}
在命令行中编写shell
### 如果/etc/default/grub文件中不存在匹配内容则添加
# if grep -q 'net.ifnames=0 biosdevname=0' /etc/default/grub; then echo "nothing to do"; else sed -e 's/GRUB_CMDLINE_LINUX="[^"]*/& net.ifnames=0 biosdevname=0/g' /etc/default/grub; fi
### 使用xargs将前面命令的执行结果转换为当前命令的变量(不过变量前面会有一个空格)
# ip addr show ens4 | grep link/ether | awk '{print $2}' | xargs echo "ATTR{address}==$1"
# ip addr show ens4 | grep link/ether | awk '{print $2}' | xargs echo "ATTR{address}==$1"
ATTR{address}== 52:54:00:c5:04:e1
### 使用下面这种方式就不会存在空格
# ip addr show ens4 | grep link/ether | echo "ATTR{address}==`awk '{print $2}'`"
ATTR{address}==52:54:00:c5:04:e1
### 查找test目录下的txt文件,并复制到当前目录
# find test/ -name *.txt | xargs -i cp {} ./
在文件中编写shell
变量的定义
# =号两边不能有空格
var="string"
var=`ls`
条件判断
#!/bin/sh
# cond两边要留一个空格,todo部分前面需要一个tab,不能是空格
if [ cond ]; then
# todo
else
# todo
fi
样例一
#!/bin/sh
# 检测目录是否存在
if [ ! -d "$HOME/test" ]; then
mkdir "$HOME/test"
fi
# 检测文件是否存在
if [ ! -f "$HOME/test/test.txt" ]; then
touch "$HOME/test/test.txt"
fi
# 检测字符串是否为空
if [ -z "$VAL" ]; then
echo "Empty string"
fi
样例二
#!/bin/sh
# 添加内容到文件
var="127.0.0.1"
if [ ! -f "/etc/rsyslog.conf" ]; then
sudo sh -c "echo 'local4.* @'${var} >> /etc/rsyslog.conf"
echo 'local4.* @'${var} | sudo tee -a /etc/rsyslog.conf
fi
样例三
#!/bin/sh
var="$1"
if [ "$var" = "0" ]; then
echo "Login"
elif [ "$var" = "1" ]; then
echo "Logout"
else
echo "Exit"
fi
实际应用
#!/bin/sh
### 由于使用for来读入文件里的行时,会自动把空格和换行符作为一样分隔符,如果行里有空格的时候,输出的结果会很乱,所以只适用于行连续不能有空格或者换行符的文件
for line in $(grep CLASSPATH /usr/lib/systemd/system/zookeeper.service.d/classpath.conf)
do
cmd="${cmd} ${line##*=}"
done
### 使用while来读入文件里的行时,会整行读入,不会关注行的内容(空格..),所以比for读文件有更好的适用性,推荐使用while循环读取文件
while read line
do
cmd="${cmd} ${line#*=}"
done < /etc/sysconfig/zookeeper
#!/bin/sh
A_VAL=$(ls)
B_VAL=`ls`