shell命令笔记
一、shell基本基础知识
1. shell命令中捕获上一个命令执行是否成功,通过判断 $? 是否为0,为0则表示成功,其他错误码则表示执行失败。
2. sheel命令中,变量赋值时默认都是字符串类型。赋值时须注意单引号与双引号的区别:
单引号:不识别特殊语法。返回字符串内的原始内容。
双引号:可以识别特殊符号。
无引号:默认字符串,但是中间有空格时容易出错,建议双引号
反引号:``,用于命令返回的结果,等同于$()的用法。比如echo `ls -l`等价于echo $(ls -l),推荐后面的这种写法。
name="奥利给"
echo ${name}
>>奥利给 #输出奥利给
name1='${name}'
echo ${name1}
>>${name} #不识别name这个变量,输出原始文字
name2="${name}"
echo ${name2}
>>奥利给 #识别了name变量,并转成其值“奥利给”
3. bash和source及.的执行区别:通过bash执行shell脚本,相当于在当前窗口进行下启动一个子进程,而通过source及.执行shell脚本,是加载到当前的shell环境中。可通过pstree查看进程树。
4. 环境变量:
用户环境配置文件:在每个用户的目录下~/.bash_profile及~/.bashrc,这两个文件在用户登录时会自动加载运行。
系统配置文件:对所有的用户生效(全局),在/etc/profile中会自动加载运行
查找环境变量:
set/declare 显示所有的变量,包括全局变量和局部变量
env 显示全局变量
export 显示和设置环境变量值(临时的)
5. 支持多条命令执行,通过分号隔开
二、shell特殊变量
1. shell的特殊变量:用于脚本、函数传递参数的时候,有如下位置特殊变量:
(1)$0 获取shell脚本文件名,脚本路径
(2)$n 获取shell脚本的第n个位置参数,n取值在1-9之间,如果大于9,则要写${10},参数空格隔开
(3)$# 获取shell脚本执行的参数总个数
(4)$* 获取shell脚本的所有参数,不加引号等同于$@。加上引号"$*"表示接收所有参数为单个字符串,即所有的参数为一个整体。
(5)$@ 获取shell脚本的所有参数,不加引号等同于$*。加上引号"$@",每一个参数都是独立的。
2. shell脚本的特殊状态变量:
(1)$? 上一次执行命令返回值,返回为0表示成功,其他则为失败
(2)$$ 当前shell脚本的进程ID,可以用来停止当前脚本的进程
(3)$! 获取上一次后台执行的进程PID,可以用来停止上一个后台执行脚本的进程。
(4)$_ 获取上次命令的最后一个参数
三、shell内置命令
echo 打印到终端,相当于简化版的printf
eval 一次执行多个命令,命令之间用分号隔开。eval ls;cd /tmd
exec 不创建子进程执行命令,并且执行完后自动执行exit
四、shell变量子串的用法
${变量} 返回变量值
${#变量} 返回变量长度,字符长度
${变量:start} 返回变量start数值之后的字符,索引从0开始
${变量:start:length} 提取start之后的length限制的字符
${变量#word} 从变量开头删除最短匹配的word子串
${变量##word} 从变量开头删除最长匹配的word子串
${变量%word} 从变量结尾删除最短的word子串,这里的word可以用正则表达式来匹配。
${变量%%word} 从变量结尾删除最长的word子串
${变量/pattern/string} 用string替代第一个匹配的pattern.如果string为空,则表示删除匹配到的字符串
${变量//pattern/string} 用string替代所有匹配的pattern。如果string为空,则表示删除匹配到的字符串
name="Jolin Su"
name1="abcABC123ABCabc"
file="/home/user/documents/report.txt"
echo ${name} >> Jolin Su #返回变量的值
echo ${#name} >> 8 #返回变量的长度
echo ${name:3} >> in Su #从索引3开始输出
echo ${name:2:3} >> lin #从索引2开始输出3个字符
echo ${name#Jo} >> lin Su #从变量开头匹配上了Jo删掉
echo ${name#lin} >> Jolin Su #需要注意lin在中间,不能匹配上开头,所以返回原来的值
echo ${name1#a*c} >> ABC123ABCabc #从开始删除a*c匹配到的最短字符串
echo ${name1##a*c} >> #返回为空,所有的字符都被删掉了,a*c最长匹配到了最后一个
echo ${file#*/} >> home/user/documents/report.txt # #*/表示移除从开头开始的第一个斜杠及其之前的所有内容。
echo ${file##*/} >> report.txt # ##*/表示移除从开头开始的所有斜杠及其之前的所有内容,直到最后一个斜杠为止。
echo ${file/o/xx} >> /hxxme/user/documents/report.txt
echo ${file//o/xx} >> /hxxme/user/dxxcuments/repxxrt.txt
echo ${name/o/} >> Jlin Su
五、shell变量扩展用法
主要用于变量值为空的判断及处理
result=${parameter:-word} 如果${parameter}为空,返回word字符串给result
result=${parameter:=word} ${parameter}为空,返回word字符串给result并且赋值给parameter
result=${parameter:?word} ${parameter}为空,返回word字符串给result,相当于错误信息输出
result=${parameter:+word} ${parameter}为空,则什么都不做;如果非空,则返回word给result
六、父子shell
shell:source script -> command1 -> command2 在同一个shell窗口执行命令
shell:/bin/bash script --> --> 命令结束后返回父shell
subshell: -->comand1 -->command2 --> 在子shell执行命令
shell:./script --> -->命令结束后返回父shell
subshell: -->command1 -->command2 --> 在子shell执行命令
#注意三种执行script的父子shell的不同,在编写脚本时需要重点注意。
七、shell算数运算
7.1 shell中常见的算术运算符
运算符 | 意义(*表示常用) |
---|---|
+、- | 加号(正号)、减号(负号)* |
*、/、% | 乘号、除号、取余(取模)* |
** | 幂运算 * |
++、-- | 增加及减少,可前置也可放在变量结尾* |
!、&&、|| | 逻辑非(取反)、逻辑与(and)、逻辑或(or)* |
<、<=、>、>= | 比较符号(小于,小于等于,大于,大于等于) |
==、!=、= | 比较符号(相等,不相等,对于字符串'='也可以表示相等) * |
<<、>> | 向左移、或向右移 |
~、|、&、^ | 按位取反,按位异或,按位与,按位或 |
=、+=、-=、*=,/=、%= | 赋值运算符,例如a+=1相当于a=a+1 |
7.2 shell中常见的算术运算命令
运算操作符与运算命令 | 意义 |
---|---|
(()) | 相当于整数运算的常用运算符,效率很高 |
let | 用于整数运算类似"(())" |
expr | 可以用于整数运算,但还有其他的额外功能 |
bc | Linux下的一个计算器程序(适合整数及小数运算) |
$[] | 用于整数运算 |
awk | awk即可用于整数运算,也可以用于小数运算 |
declare | 定义变量值和属性,-i参数可以用于定义整形变量,做运算 |
- 双小括号(())
运算操作符与运算命令 | 意义 |
---|---|
((i=i+1)) | 此写法为运算后赋值法,即将i+1的结果赋值给变量i。注意,不能用echo ((i=i+1))的形式输出表达式的值,但可以用echo $((i=i+1) |
i=$((i+1)) | 可在(())符号前面加$符,表示将表达式运算结果赋值给i |
((8>7&&5==5)) | 可以进行比较操作,还可以加入逻辑与和逻辑或,用于条件判断 |
echo $((2+1)) | 需直接输出运算表达式的运算结果时,可在(())前加$符 |
2. ++a和a++的区别
++a,先计算+1,在赋值给a
a++,先对变量a操作,再进行+1
a=5
echo $((a++)) #结果是5,先打印然后再+1赋值给a
echo $a #结果是6
b=5
echo $((++b)) #结果是6,先对b+1,再打印
echo $b #结果是6
7.3 expr命令
常用来做模式匹配,用法
expr string : ".*" #string为字符串对象,:为固定格式,表示匹配统计后面表达式的匹配到的长度。 ".*"这里.是固定的,*为正则表达式,可以根据需要修改。
7.4 bc工具
前面的字符通过管道符|交给bc来运算,并打印返回结果
echo "3*3.5" | bc #返回结果10.5
7.5 awk命令
echo "2.2 3.5" |awk '{print ($1 + $2)}'
八、条件判断
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
补充说明:shell脚本中命令支持&&和||的用法,&&表示前面的条件为真才执行,||前面的条件不成立才执行。举例:
test -e hello.txt && echo "文件存在" || echo "文件不存在"
test命令和[ ] 的使用,判断里面的条件表达式是否为真,为真则返回0,否则非0。
注意:
1. [ ] 里面的条件,在左右括号的前后必须有空格。
2. 在[ ]条件判断中,变量引用必须加上双引号" "。
3. [[ ]]双中括号的条件判断,可以更灵活;支持 &&
和 ||
逻辑运算符;而[ ] 要实现逻辑表达需要使用 -a 或者 -o 分别表示and和or。!表示非。
参数如下:
8.1 数值测试
参数 | 说明 |
---|---|
-eq | 等于则为真 |
-ne | 不等于则为真 |
-gt | 大于则为真 |
-ge | 大于等于则为真 |
-lt | 小于则为真 |
-le | 小于等于则为真 |
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
8.2 字符串测试
参数 | 说明 |
---|---|
= | 等于则为真 |
!= | 不相等则为真 |
-z 字符串 | 字符串的长度为零则为真 |
-n 字符串 | 字符串的长度不为零则为真 |
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
8.3 文件测试
参数 | 说明 |
---|---|
-e 文件名 | 如果文件存在则为真 |
-r 文件名 | 如果文件存在且可读则为真 |
-w 文件名 | 如果文件存在且可写则为真 |
-x 文件名 | 如果文件存在且可执行则为真 |
-s 文件名 | 如果文件存在且至少有一个字符则为真 |
-d 文件名 | 如果文件存在且为目录则为真 |
-f 文件名 | 如果文件存在且为普通文件则为真 |
-c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
-b 文件名 | 如果文件存在且为块特殊文件则为真 |
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
九、条件判断
9.1. if语句来判断
#单条件循环
if [ ];then
执行代码
fi
#两条件循环
if [ ];then
执行代码
else
执行代码
fi
#多条件循环
if [ ];then
执行代码
elif [ ]
执行代码
else
执行代码
fi
9.2 case语句(多条件模式匹配)
#!/bin/bash
echo "请输入一个数字 (1-3 或其他): "
read number
case $number in
1|2|3)
echo "你输入了一个 1 到 3 之间的数字"
;;
[4-9])
echo "你输入了一个 4 到 9 之间的数字"
;;
[0-9]*)
echo "你输入了一个多位数"
;;
*)
echo "你输入的不是一个数字"
;;
esac
- 双分号 (
;;
):- 每个命令块以
;;
结尾,表示命令块的结束。 - 最后一个命令块(通常是默认情况)可以省略
;;
。
- 每个命令块以
- 使用
esac
:esac
是case
语句的结束标志,是case
的反向拼写。
十、函数
#函数的基本定义
function test(){
定义函数的动作
}
#函数调用
test
1. 函数必须先定义,再执行,从上往下执行
2. 函数体内定义的变量,为局部变量,仅在函数体内有效
3. 函数体内当有需要返回值时,添加return语句,作用是退出函数,且将返回值赋值给调用程序,在shell中通过$?获取其return的值
4.return语句和exit语句的差异:
(1)return是退出函数,只能写在函数中,给出返回值
(2)exit是shell内置命令,是退出shell脚本的执行,并返回码
5. 函数如果单独写入一个文件里,需要通过source读取
6.