1 Shell解析器
Linux提供的shell解析器有6种:
/bin/sh
/bin/bash
/sbin/nologin
/bin/csh
/bin/dash
/bin/tash
sh是bash的软连接。
2 Shell脚本
2.1 hello.sh脚本
#!/bin/bash
echo 'hello world!'
#! 告诉系统这个脚本需要什么解释器来执行;
脚本以#!/bin/bash开头;
echo表示输出。
文件扩展名 .sh 不是强制要求的。
运行:
# 方法1 直接运行解释器,hello.sh 作为 Shell 解释器的参数。
# 本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限
# 此时 Shell 脚本就不需要指定解释器信息,第一行可以去掉。
sh hello.sh
# 或
bash hello.sh
# 方法2 hello.sh 作为可执行程序运行,Shell 脚本第一行一定要指定解释器。
# 本质是自己执行脚本,必须先赋予权限
chmod +x hello.sh # 一定要先赋予脚本的+x权限,之后才能执行以下
./hello.sh
2.2 多命令处理脚本
需求:创建一个test.txt文件,使用脚本在文件中增加一行“test shell”字符。
(1)创建batch.sh脚本并编辑:
touch batch.sh
#!/bin/bash
cd /shell_stady/
#创建test.txt文件
touch test.txt
#将一句字符添加到test.txt文件中
echo "test shell " >> test.txt
(2)执行batch.sh
sh batch.sh
可以看到文件夹里多了一个test.txt文件。
(3)把test.txt文件内容显示到控制台上:
cat test.txt
3 Shell变量
3.1 显示当前变量的值
echo $变量名 #引用变量的值
set #一次性显示当前shell中所有变量的名称值
env #显示环境变量
printenv PATH #显示指定变量和值
3.2 自定义变量
3.2.1 基本语法
定义变量:变量名=值
A=122
撤销变量:unset 变量名
unset A
echo $A
声明静态变量:readonly 变量名=值,静态变量只能读,不能撤销unset掉。
readonly B=234
变量定义规则:
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格。
(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来,表示变量值为一个字符串。
(5)可把变量提升为全局环境变量,可供其他Shell程序使用。
3.2.2 配置环境变量
(1)export 变量名=变量值 (功能描述:将shell变量输出为环境变量)
(2)source 配置文件 (功能描述:让修改后的配置信息立即生效)
(3)echo $变量名 (功能描述:查询环境变量的值)
export 变量名:把变量提升为全局变量。
例如:先定义一个变量D,默认为局部变量。
D="this is shell_stady."
编辑hello.sh
#!/bin/bash
echo 'hello world!'
echo $D
运行hello.sh发现$D并没有输出。
此时需要把局部变量D提升为全局变量:
export D
重新运行hello.sh。
3.3 特殊变量
3.3.1 $n
$n:n为数字,$0 代表该脚本名称(即文件),$1-9代表第一到第九个参数,十以上的参数需要用大括号包含如${10}
创建编辑parameter.sh
touch parameter.sh
vim parameter.sh
# 输入以下
#!/bin/bash
echo "$0 $1 $2 $3"
运行:
应用于:判断输入的参数,即脚本根据输入的参数执行相应的内容。
3.3.2 $#
$#:用于获取所有输入参数个数,常用于循环。
继续在parameter.sh末尾加上:
echo "$#"
运行:
3.3.3 $*、 $@
$*:代表命令行中所有的参数,即把所有的参数看成一个整体。
$@:也代表命令行中的所有的参数,不过把每个参数区分对待。
继续在parameter.sh末尾加上:
echo "$*"
echo "$@"
运行:
3.3.4 $?
$?:最后一次执行的命令的返回状态。如果这个变量的值为0,说明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则说明上一个命令执行不正确。常用于判断异常。
3.3.5 $$
$$:表示当前进程的进程号(PID)。
3.3.6 $!
$!:表示后台运行的最后一个进程的进程号(PID)。
4 运算符
语法:
(1)$((运算式)) 或 $[运算式] (推荐使用第二种);
(2)expr +,-,*, / ,% 加,减,乘,除,取余。(expr 与运算符之间要有空格)
例子1:混合运算:(2+3)*4
或创建一个calculate.sh
#!/bin/bash
temp=`expr 2 + 3`
result=`expr $temp \* 4`
echo "result=$result"
例子2:求两个输入参数之和。
创建getAaddB.sh
!#/bin/bash
#求两个输入参数之和
echo "$1 $2"
result=$[$1 + $2]
echo "$1与$2之和为$result"
5 条件判断
5.1 判断语句
语法:[ condition ] ps:condition前后都要有空格。
条件非空几即为true,如:[ test ]返回true,[ ]返回false。
5.2 常用判断条件
5.2.1 两个整数之间的比较
= 字符串比较
-eq 等于(equal)
-ne 不等于(Not equal)
-lt 小于(less than)
-le 小于等于(less equal)
-ge 大于等于(greater equal)
-gt 大于(greater then)
5.2.2 判断文件权限
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
判断文件是否有写权限:
5.2.3 判断文件类型
-b 是否是块设备文件
-c 是否是字符设备文件
-d 文件存在并不是一个目录(directory)
-e 文件存在 (existence)
-f 文件存在并且是一个常规的文件(file)
-L 是否是软链接文件
-s 文件是否非空
-S 是否是套接字文件
-p 是否是管道文件
判断目录中的文件是否存在:
5.2.4 多条件判断
&&表示前一条命令执行成功时,才执行后一条命令;
|| 表示上一条命令执行失败后,才执行下一条命令。
6 流程控制
6.1 if 判断
语法:
# [ 条件判断式 ] 判断式两边必须要有空格
# if后要有空格
if [ 条件判断式 ]:then
程序
fi
# 或者
if [ 条件判断式 ]
then
程序
fi
例子:创建if.sh
#!/bin/bash
echo "$1"
if [ $1 -ge 5 ]
then
echo "输入值大于5"
elif [ $1 -gt 3 ]
then
echo "输入值大于3"
elif [ $1 -le 3]
then
echo "输入值小于等于3"
fi
6.2 case 语句
语法:
case $变量名 in
值1)
如果变量的值等于值1,则执行程序1
;; # ;;表示命令序列结束,相当于Java中的break
值2)
如果变量的值等于值2,则执行程序2
;;
...省略其他分支...
*) #表示默认模式,相当于Java中的default
如果变量的值都不是以上的值,则执行此程序
;;
esac
例子:
#!/bin/bash
case $1 in
1)
echo "beijing"
;;
2)
echo "shanghai"
;;
*)
echo "guangzhou"
;;
esac
6.3 for 循环
语法一:
# for后要有空格
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
例子:1累加到10。
#!/bin/bash
s=0
for ((i=0;i<=10;i++))
do
s=$[ $s + $i ]
done
echo "result=$s"
语法二:
for 变量 in 值1 值2 值3...
do
程序
done
例子:打印所有输入的参数,并区别四种情况。
(1)
#!/bin/bash
for i in $*
do
echo "输入的参数是$i"
done
(2)
#!/bin/bash
for i in $@
do
echo "输入的参数是$i"
done
(3)“$*” 加引号的,一次输出所有,只循环一次。
#!/bin/bash
for i in "$*"
do
echo "输入的参数是$i"
done
(4)
#!/bin/bash
for i in "$@"
do
echo "输入的参数是$i"
done
总结:
$@、$*、"$@",参数有几个就循环几次。
"$*"不管参数有多少个,它只循环一次,并且值就是所有的值。
6.4 while 循环
语法:
# while后要有空格
while [ 条件表达式 ]
do
程序
done
例子:1累加到10。
#!/bin/bash
s=0
i=0
while [ $i -le 10 ]
do
s=$[ $s + $i ]
i=$[ $i + 1 ]
done
echo $s
7 read读取控制台输入
语法:read(选项)(参数)
选项:
-p:指定读取值时的提示符
-t:指定读取值时等待的时间(秒)
参数:
变量:指定读取值的变量名
例子:提示7秒内读取控制台输入的名称。
#!/bin/bash
read -t 7 -p "input your name" NAME
echo $NAME
8 函数
8.1 系统函数
8.1.1 basename
语法:basename 字符串或路径名 后缀
返回完整路径最后的“/”的部分,常用于获取文件名。
basename命令会截取所有前缀,包括最后一个“/”字符,然后显示。
如果后缀被指定,basename会把该字符串或者路径名中的后缀去掉。
例子:返回 /shell_stady/hello.sh路径的文件名称。
8.1.2 dirname
语法:dirname 文件绝对路径
返回完整路径最后的“/”的前面的部分,常用于返回路径部分。
从指定包含绝对u就的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录部分)。
例子:返回 ./shell_stady/hello.sh的 ./shell_stady
8.2 自定义函数
语法:
function funname ()
{
程序;
return 参数;
}
# 调用直接写函数名
funname 参数
例子:计算输入两个参数和。
#!/bin/bash
function getSun()
{
SUM=$[ $A + $B ]
echo "$A+$B=$SUM"
}
read -p "请输入第一个数" A
read -p "请输入第二个数" B
# 调用函数getSun
getSun $A $B
9 Shell工具
9.1 cut
负责在文件中剪切数据,cut从文件的每一行剪切字节、字符、字段,并将这些字节、字符、字段输出。
语法:cut 选项参数 filename
默认分隔符为Tab。
选项参数:
-f:列号,提取第几列
-d:分隔符,按指定分隔符分隔。
例子1:创建cut.txt
vim cut.txt
beijing tianjing
hangzhou shanghai
guangzhou shenzhen
例子2:切割环境变量PATH。
例子3:切割ifconfig打印后的ip地址。
9.2 sed
sed一次处理一行内容,把导航前处理的行存储在临时缓冲区(称模式空间);然后用sed命令处理缓冲区的内容;处理完成后将缓冲区的内容输出到控制台;重复直到文件末尾。
语法:sed 选项参数 “操作(带命令)” filename
参数选项:
-n:按行取。
-e直接在指令列模式上进行sed动作编辑。
命令描述:
a:新增一行,直接在a后接字符串。
d:删除。
s:查找并替换。
9.3 awk
awk是文本分析工具,把文件逐行读入,默认分隔符为空格,对读入的行进行切片再分析处理。
语法:awk 选项参数 ‘pattern1 {action1} pattern2 {action2}…’ filename
pattern:表示awk在数据中查找内容,即匹配模式,在匹配正则表达式时用:/正则表达式/
action:在找到指定内容时所执行的一系列命令。
只有匹配了pattern的行才会执行action。
选项参数:
-F:指定文件拆分符。
-v:赋值一个用户定义变量。
awk内置变量(在action内的变量):
FILENAME:文件名
NR:已读的记录数
NF:浏览的域的个数(切割后列的个数)
例子1:先把 /etc/passwd复制到shell_stady目录下,取以root开头的行的第1列和第7列。
例子2:BEGIN在所有数据读取行之前执行,END在所有数据执行之后执行。
例子3:
例子4:统计passwd文件名,每行的行号,每列的列数
例子5:切割IP。
例子6:查询sed.txt中空行所在的行号。
9.4 sort
对文件排序并输出。
语法:sort 选项参数 参数
选项参数:
-n:按照数值大小排序
-r:以相反的顺序排序
-t:设置排序时用的分割符
-k:指定需要排序的列
例子:创建sort.txt
aa:2:3.2
bb:1:5.4
cc:5:2.2
dd:8:1.2
fa:5:1.2
ab:3:4.3
10 Shell常用命令
10.1 目录
pwd #确定现在所处的目录
cd #切换目录
ls #显示目录
#参数:
-a :显示包括隐藏文件和目录在内的所有目录和文件
-l :显示文件的详细信息
-h :配合-l以人性化的方式显示文件大小
-t :按文件最后修改时间排序文件
一行共10位:
1.表示文件类型:d表示目录,-表示文件,l表示链接文件,b表示可随机存取的设备,如U盘等,c表示一次性读取设备,如鼠标、键盘等。
2.owner身份所拥有的权限:readable、writable、excutable(读、写、执行)。
3.group身份所拥有的权限:readable、writable、excutable(读、写、执行)。
4.others身份所拥有的权限:readable、writable、excutable(读、写、执行)。
5.表示链接数,即有多少个文件链接到该文件。
6.表示拥有者。
7.表示所属群组。
8.表示文档容量大小,单位字节。
9.表示文档最后修改时间,注意不是文档的创建时间。
10.表示文档名称。以点(.)开头的是隐藏文档。
权限数字表示法:
10.2 文件和文件夹
mkdir #创建文件夹
#参数:
-p :递归创建目录
-m:设置新建目录权限
rmdir #删除文件夹
#参数:
-p :递归删除目录
touch #创建文件
cat #查看文件内容
vim #编辑文件
rm #删除文件
#参数:
-f :强制删除文件。
-r :递归删除目录及内容
chmod #修改目录和文件权限
#参数:
-u user 用户
-g grop 用户组
-o others 其他人
-a all 所有人
10.3 输出重定向
# 输出重定向,用">"将输出的内容保存到文件中,
# 如果文件中有内容则会覆盖该文件所有的内容
echo '新加的内容' > test.txt
# 追加输出重定向,用">>"将内容追加输出到文件中末尾
echo '新加的内容' >> test.txt
10.4 别名
# 别名:命令、参数可以由另外一个命令执行来代替。
alias 别名='需要定义的名称、参数、命令' #取别名
unalias 别名 #取消别名
10.5 命令
# 管道命令:管道中的前一条命令的输出转为下一条命令的输入。
命令1 | 命令2 | 命令3 | ... | 命令n
命令1;命令2;命令3 # 表示顺序执行若干命令
命令1 && 命令2 # 表示命令1运行成功才运行命令2
命令1 || 命令2 # 表示命令1运行不成功才运行命令2
11 正则表达式
^:匹配字符串的开头。
$:匹配字符串的结尾。
.:匹配除换行符外的任意一个字符。
*:匹配前一个字符零次或多次。
+:匹配前一个字符一次或多次。
?:匹配前一个字符零次或一次。
[]:匹配其中任意一个字符,常用于指定一组字符。
[^]:不包含其中任意一个字符,常用于排除一组字符。
|:匹配左右两边任意一个表达式。
():捕获匹配到的子字符串,可以使用反向引用来重复使用。