Linux运维基础学习-第二章
目录
2.1正则
\<\> 精确匹配
$ 以什么结尾
\{n\} 字符出现n次
\{n,\} 至少出现n次
\{n,m\} 出现n-m次间
2.2变量
#清除变量
unset 变量名
#只读变量
变量名=值
readonly=变量名
2.2.1内部参数变量
内部参数变量与含义
内部参数 | 含义 |
$@ | 传递给函数或脚本所有参数。被双引号包含时,与$*不同 |
$* | 传递给函数或脚本所有参数 |
$0 | 命令行上输入的shell程序名 |
$# | 命令行参数个数 |
与进程相关的内部参数含义
内部参数 | 含义 |
$? | 上条命令执行后的返回值 |
$$ | 当前进程的进程号 |
$! | 进程运行在后台的最后一个PID |
$_ | 之前命令或脚本的最后一个参数 |
2.2.2退出返回状态
设置exit退出状态码
exit n
n取值:
状态码 | 含义 |
0 | 成功 |
1 | 失败或错误 |
126 | 没有权限 |
127 | 命令没有找到 |
2.2.3变量测试与截取
变量 | 含义 |
${var:-word} | 若变量存在且非空,则值为$var.若未定义或空值,则值为word,但var的值不变 |
${var:=word} | 若变量存在且非空,则值为$var.若未定义或空值,则值为word,且var的值=word |
${var:?word} | 若变量存在且非空,则值为$var.若未定义或空值,则输出信息word,并终止脚本 |
${var:+word} | 若变量存在且非空,则值为word,否则返回空值,但var值不变 |
2.2.4字符串长度、截取、替换
字符变量 | 含义 |
${#var} | 字符串变量长度 |
${var:m} | 截取第m个字符后的部分 |
${var:m:len} | 截取第m个字符后,长度为len的部分 |
${var#pattern} | 删除${var}中开头部分与pattern匹配的部分 |
${var%pattern} | 删除${var}中结尾部分与pattern匹配的部分 |
字符变量 | 含义 |
${var/old/new} | 用new替换第一次出现的old |
${var//old/new} | 用new替换所有出现的old |
${var/#old/new} | 用new替换开头出现与old匹配的部分 |
${var/%old/new} | 用new替换结尾出现与old匹配的部分 |
2.2.5变量的间接引用
x=”aa”
y=x
eval echo \$$y
2.2.6算术运算
格式: $[] 或$(())
算术指令:expr
expr \(2+5\) \*2-6 |
算术指令:let
num=1 let num=4+6 |
2.3条件测试
格式:
test 表达式
[表达式]
[[表达式]]
2.3.1整数的判断与比较
符号 | 含义 |
-eq | 等于(equal) |
-ne | 不等于(not equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater or equal) |
-lt | 小于(less than) |
-le | 小于等于(less or eaual) |
; 按顺序执行,退出码以最后命令为准
&& 仅当前一条命令成功才执行&&后的命令
|| A命令||B命令 A命令一定执行,A成功不执行B,A失败执行B,有任何一个返回码为0,整个命令返回码都为0
2.3.2 字符串的判断与比较
test a == b ; echo $? test a != b ; echo $? 退出码0为正确,非0为错误
[ $USER == root ] && echo Y || echo N
-z 测试字符串是否为空 [ -z "$Test" ] && echo Y || echo N 为空输出Y
-n测试字符串是否不为空 [ -n "$Test" ] && echo Y || echo N 为空输出N
[ -a FILE ] 如果 FILE 存在则为真。
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。 [ -h FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。
[ -o OPTIONNAME ] 如果 shell选项 “OPTIONNAME” 开启则为真。
[ -z STRING ] “STRING” 的长度为零则为真。
[ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。
[ STRING1 == STRING2 ] 如果2个字符串相同。 “=” may be used instead of “==” for strict POSIX compliance则为真。
[ STRING1 != STRING2 ] 如果字符串不相等则为真。
[ STRING1 < STRING2 ] 如果 “STRING1” sorts before “STRING2” lexicographically in the current locale则为真。
[ STRING1 > STRING2 ] 如果 “STRING1” sorts after “STRING2” lexicographically in the current locale则为真。
2.3.3文件属性判断与比较
操作符 | 功能描述 |
-e | 判断目录或文件是否存在,存在返回为真 |
-f | 判断目录是否为普通文件 |
-d | 判断存在且为目录 |
-b | 判断存在且为块目录(磁盘,u盘等) |
-c | 判断存在且字符设备(键盘,鼠标等) |
-L | 判断是否为软连接 |
-p | 判断存在且为命名管道 |
-r/-w/-x | 判断当前用户对该文件具有可读/可写/可执行权限 |
-s | 判断存在且大小非空 |
file1 –ef file2 | 2文件使用相同设备,相同设备号则返回真 |
file –nt file2 | 文件1比文件2新,或者文件1存在而文件2不存在返回真 |
File –ot file2 | 文件1比文件2旧,或者文件2存在而文件1不存在返回真 |
[ -b /dev/sda ] && echo 存在 || echo 不存在
软连接:源文件被删除,软连接无法使用,可以跨分区和磁盘创建
ln –s /源文件 /软连接地址
硬链接:源文件不影响硬链接,单不可以跨分区与磁盘创建
ln /源文件 /软连接地址
2.3.4[[]]与[]的区别
多数情况下是通用的,test和[]是符合POSIX标准的,兼容性更强几乎可以运行在所有的shell解释器中,而[[]]仅仅运行在特定的几个解释器(Bash,Zsh等)
区别:[[]]使用符号<和>时,是进行排序操作且支持表达式使用&&和||,==模式匹配
test和[]不允许使用,=可以使用 –a表示&& -o表示||,不支持正则,==字符匹配
ASCII码顺序:小写字母>大写字母>数字顺序码
Bash常用通配符:* ? […]
ls /dev/sda[1-5]
ls [0-9]?.conf
ls [xyz]*.txt
name=tom
[ $name = [Tt]?? ]
echo $?
>1
--------------------
[ [ $name = [Tt]?? ] ]
echo $?
>0
2.3.5判读字符串是否为空
判读字符串是否为空 |
|
|
|
|
判读字符串是否为非空 |
1. [ “$name” != “” ] |
2. [ -n “$name” ] |
3. [ “$name” ] |
4. [ “X${name}” != “X” ] |
2.4判断循环
2.4.1if/else
1.简单结构 |
if <测试条件> then 命令 fi |
2.if/else结构 |
if <测试条件> then 命令 else 命令 fi |
3.if/elif/else结构 |
if <测试条件> then 命令 elif <测试条件> then else 命令 fi |
2.4.2case选择
格式: case expr in p1) 命令 ;; P2) 命令 ;; *) 命令 ;; esac |
2.4.3for循环
#列表带空格使用双引号
for x in "x1" "x 2" x3
do
echo "$x"
done
#eval 将$x替换为命令并执行
for x in "df -h" "du -sh"
do
ehco "--$x--";eval $x
done
#for+case
i=1
for day
do
echo –n "$((i++)): $day"
case $day in
[Mm]on | [Tt]ue | [Ww]ed | [Tt]hu | [Ff]ri)
echo "(weekday)"
;;
[Ss]at | [Ss]un)
echo "(weekend)"
;;
*)
echo "(erro)"
;;
esac
done
#将目录下所有大写文件名改为小写
for fname in *
do
fn=$(echo $fname | tr A-Z a-z)
if [[ $fname != $fn ]];then
mv $fname $fn
fi
done
2.4.4while
#读取文件
cat /etc/passwd | while read lline
do
echo $line
done
file=/etc/passwd
while IFS = read –r line
do
echo $line
done < “$file”
#将当前目录下带有空格的文件名替换为下划线
dir=”.”
find $dir –type f | while read file
do
echo $file
if [[ “$file” = “*[[:space:]]*” ]];then
mv “$file” $(echo $file | tr ‘ ’ ‘_’)
fi
done
#计数器控制while
c = 1
while [ $c –lt 10 ];do
let “count+=1”
echo “$count”
done
#结束标记的while循环
read –p "xxxxxxx" var
while [[ $var != ok ]];do
read var
echo $var
done
#标志控制的while循环
signal=0
while (( singal !=1 ))
do
if [[ $@ = ok ]];then
signal=1
fi
done
2.4.5until
#ping通则ssh
read –p “pleas input ip” ipadd
until ping –c l $ipadd &> /dev/null
do
sleep 10
done
ssh $ipadd
username=$1
# $#表示输入参数个数
if [ $# -lt 1 ];then
echo "请输入参数用法:`basename $0` <usename>"
exit 1
fi
if grep "^$username:" /etc/passwd > /dev/null ;then :
else
echo "$username is not a user on this system"
exit 2
fi
until who | grep "$username" > /dev/null ;do
echo "$username is not logged on"
sleep 5
done
2.4.6select 循环与菜单
格式: select car in list do commands done |
2.5函数