shell:用户通过shell与操作系统内核进行交互。
cat /etc/shells 查看当前系统有哪些shell.
shell脚步范例:
#!/bin/bash
#第一行表示指定脚本解释器,带‘#’号的是注释。
#去除字符中的所有空格
echo " hello , my name is bob " | tr -d " "
#输出100以内所有3的倍数
for i in {0..100..3}
do
echo $i
done
#获取用户输入
read -p "你输入你的名字:" name
echo "你的名字是$name"
...
shell名字 --version 查看shell版本
shell名字 回车后,进入相应shell,退出输入:exit
执行shell脚本两种方式:
- chmod 755 ts.sh
./ts.sh - bash ts.sh
&,后台运行。
后台运行的,可用jobs来查看。
shell中的变量
shell中所有变量都是字符串。
字母,数字,下划线组成,不能以数字开头。
str='hello\tworld' : 单引号,不解析特殊字符。
str="hello\tworld": 双引号,解析特殊字符。
now_date=`date`:反引号,执行命令后赋值给变量。
str=hello,world:也可以什么都不加,但这时若变量的值中有特殊字符,就不能正确解析。
推荐还是用双引号表示字符串。
length=${#str}:获取变量的长度。
substr=${str:1:3}:字符串切片。
变量分类
环境变量:主要保存的是和系统操作环境相关的数据,系统预定的变量名不可改变,值可改变,还可新增变量。
位置参数变量:主要用来向shell脚本传递参数,数据。变量名不能自定义,作用固定。
预定义变量: bash中预先定义的变量,变量名不能自定义,作用固定。
用户自定义变量:用户自己定义的变量,名和值可随时修改。
变量的使用和判断
变量调用:${var} 或者 $var
命令调用:$(command) 或者 `command`,这里是反引号。
判断真或假:[ 表达式 ],[[ 表达式 ]],test 表达式
算术运算:C=$(($A+$B)),双小括号。
name="taylor swift"
[ $name == "taylor swift"]
报错:-bash: [: too many arguments
相当于:[ taylor swift == "taylor swift" ]
改用双中括号:
[[ $name == "taylor swift" ]]
不报错。
注意 单双中括号的 空格。
双中括号中,等号右边的 不加双引号可以当成匹配模式,加了双引号就只是 字符串了。
[[ $name == tay* ]] 这里的*是shell中的元字符,不是正则!!
echo $?
0 # 0,代表上一条命令执行正确。
位置参数变量
$0:shell脚步本身文件名。
$1-$9:执行脚本时传递进来的参数,$1代表第一个参数。
$*:所有参数。
$#:传递的参数总数。
$?:判断上一个命令是否正确执行,正确返回0,错误返回非0。
设置变量
export 变量=变量值 :声明环境变量
变量=变量值:声明普通变量
env:查询环境变量
unset 变量名:删除变量
$变量名:引用变量
set:查看系统所有变量
环境变量的值以冒号分隔。
PATH,是搜索命令的路径。
添加新值(/root/xyz)到环境变量,这里用的是变量叠加。比如:PATH="$PATH":/root/xyz
或者 PATH=${PATH}:/root/xyz
服务
服务:后台运行的程序(daemon,守护进程),一般随系统的启动而自动启动,在用户登出后还能继续运行。
服务的自启动,修改/etc/rc.local文件。
若你有需要每次开机自动启动的程序,可以添加到该文件里。
启动脚本位置(run level control directory)
/etc/init.d/
/etc/rc数字.d/ rc,代表运行级别,该目录下的文件都是链接文件,指向/etc/init.d/下对应的文件。
7种运行级别
0:关机
1:单用户
2:无网络的多用户
3:命令行模式
4:未用
5:GUI(图形桌面模式)
6:重启
运行级别的切换:init 想要切换的运行级别
查看当前级别:who -r
显示前一个运行级别(无则显示”N”) 、 当前运行级别: runlevel
配置文件位置
/etc/
服务产生的数据
/var/lib/
service --status-all 查看服务列表。其中前面的"+"表示正在运行,"-"表示停止运行。
service 服务名 start/stop/restart/status
service 命令就是在 /etc/init.d/目录下寻找相应服务的脚本文件,再执行相应操作。
日志
/var/log/
日志服务:rsyslogd
ps -aux | grep rsyslogd 查看是否运行。
/etc/rsyslog.conf 配置文件。
日志轮替
/etc/logrotate.conf 配置文件。
若是源码包安装的程序,其日志若需要轮替,要手动加入到上面的配置文件。
logrotate -v /etc/logrotate.conf 查看日志轮替过程。
若带上参数 -f,表示强制进行日志轮替,没到时间也轮替。
定时任务
这里用的是debian9,其他系统可能有差异。
检测当前进程中是不是有cron服务:pgrep cron 若有,返回进程号。
/etc/init.d/cron start 启动服务
/etc/init.d/cron stop 停止服务
/etc/init.d/cron restart 重启服务
crontab -u 用户名 一般root用户才会执行这个命令去查看其他用户的定时任务,比如:crontab -u xiao -l
crontab -e 编辑当前用户定时任务
当编辑完定时任务后,不需要重启cron服务就可以生效,
并且会在 /var/spool/cron/crontabs/下生成一个以 当前用户名 命名的文件。
crontab -l 查看当前用户已经存在的定时任务
crontab -r 删除当前用户定时任务
select-editor,选择定时任务的编辑器。
/etc/crontab 这个文件相当于是全局的crontab
编辑定时任务:
格式:* * * * * 要执行的命令
注意,星号之间有空格。
这5个星号,星号本身代表 所属位置 的任意取值。
从左到右依次表示:分钟,小时,日,月,周。
/:后面接数字n,表示 每n。
,:逗号分隔多个数字。
-:表示一个范围,比如 5-8,表示5,6,7,8.
windows中回车符:^M$
linux中回车符: $
cat -A ts.sh # -A表示显示不可打印字符
若在windows中写的shell,放到linux中去执行可能报错。
解决方法两种:
1.直接指定解释器执行:bash ts.sh
2.apt-get install dos2unix , 然后 dos2unix ts.sh , 再执行该ts.sh
输出重定向:
>表示覆盖
>>表示追加
0表示标准输入
1表示标准输出
2表示标准错误输出
命令1 &>>a.log
&表示执行命令1命令,不管对错,都将结果以追加的形式写入a.log文件。
命令1 >>a.log 2>>b.log
表示执行命令1,将正确的结果追加到a.log,错误的结果追加到b.log
多命令执行:
; 分号表示多个命令没任何关系,只是起分隔作用。
&& 逻辑与,遇到假,返回。前一个命令正确执行,才执行后一个命令。
|| 逻辑或, 遇到真,返回。前一个命令正确执行,后一个命令就不执行。
chmod 数字
r:4
w:2
x:1
比如 chmod 755代表的权限是:rwxr-xr-x
crontab的命令构成为 时间+动作,其时间有分、时、日、月、周五种,操作符有
* 取值范围内的所有数字
/ 每过多少个数字
- 从X到Z
,散列数字
注意:日,周 之间是或的关系。
让配置文件立即生效:
"source 配置文件"或者". 配置文件",这里是点+空格。
常见的环境变量配置文件:
/etc/profile
/etc/profile.d/*.sh
~/.bash_profile
~/.bashrc
/etc/bashrc # 定义了一些不需要登录时(启用子shell)生效的环境变量。
基本上是从上到下的加载顺序,加载完毕,你就可以看到命令提示符窗口了。
保存在/etc下的配置文件,对所有登录的用户有效。
保存在~/即家目录下的配置文件,只对当前用户有效。
注销时生效的环境变量配置文件:~/.bash_logout
历史命令的环境变量配置文件:~/.bash_history
umask 系统默认权限
cut [选项] 文件名
grep是提取行,cut是提取列。
grep -v 取反。
若分隔符是空格的话,cut命令不好用。
选项:
-f 列号,提取第几列,多列之间用","分隔。
-d 分隔符,按照指定分隔符分隔列
printf
格式化输出
printf '输出类型输出格式' 输出内容
不能用管道符作为输入,输出内容若是一个文件,要用$(cat xx)或者`cat xx`。
输出类型:
%s:字符串
%i:整数
%f: 浮点数
输出格式:
\n :换行
\r :回车
\t :制表符 tab
grep
全称:global search regular expression(RE) and print out the line
格式:grep [ 参数 ]条件 files
参数:
-n:显示行号
-i:忽略大小写
-c:统计次数
-v:取反
--color=auto:将搜索字符串加上颜色
-q:安静模式,即不打印查询结果,若查询字符串存在,则返回0.常用在 if 判断中。
-w: 精确匹配。
-E:grep -E 'abc|xyz' files 表示找出文件中包含'abc'或者'xyz'的行。
-l:grep -l abc files 表示列出包含字符串"abc"的文件的文件名。
-L:与-l相反。
awk
提取列,默认识别 制表符 和 空格 作为分隔符。
awk会将多个连续的空白看做一个单一的记录分隔符。
示例:
awk 'BEGIN {print "这是一个测试";FS="%"} {print $2 "\t" $6}' a.txt
{}中的语句之间用“;”分隔。
其中$表示列,BEGIN代表在执行之前输出一次"这是一个测试"。
FS="%",指定分隔符,这里指定以%作为分隔符。
NF=一行中的字段数。
NR=行数。
支持浮点数计算。
若a文件内容如下:
id name gender mark
1 xyz male 90
2 lee female 78.22
3 lily female 99
执行:
cat a | grep -v name | awk '$4 >=79{print $2}'
'条件{}'等价写法==> '{if(条件){}}'
cat a | grep -v name | awk '{if($4 >=79){print $2}}'
结果:
xyz
lily
从a文件中,提取出包含字符“fe”的行。
执行:awk '/fe/' a
结果:
2 lee female 78.22
3 lily female 99
通过 -F '[分隔符1分隔符2]'空格'{print xxx}' 来指定多个分隔符。
这里是 [] , | 是正则匹配。
echo "My name is xyz,my mobile is 123456" >> b.txt
awk -F '[ ,]' '{print $4"\t"$8}' b.txt
或者这样写
awk -F ' |,' '{print $4"\t"$8}' b.txt
结果:
xyz 123456
统计某个目录下,文件总大小
ls -al
结果:
total 32
drwxr-xr-x 3 root root 4096 Aug 15 01:37 .
drwx------ 13 root root 4096 Aug 14 12:16 ..
-rw-r--r-- 1 root root 200 Aug 15 00:25 a
-rw-r--r-- 1 root root 9766 Aug 15 01:37 b
drwxr-xr-x 2 root root 4096 Aug 14 11:53 sh
-rw-r--r-- 1 root root 977 Aug 14 22:43 ts
ls -al|awk 'BEGIN{size=0;print"开始统计。。"}{size=$5+size;print$0}END{print"文件总大小:"size}'
结果:
开始统计。。
total 32
drwxr-xr-x 3 root root 4096 Aug 15 01:37 .
drwx------ 13 root root 4096 Aug 14 12:16 ..
-rw-r--r-- 1 root root 200 Aug 15 00:25 a
-rw-r--r-- 1 root root 9766 Aug 15 01:37 b
drwxr-xr-x 2 root root 4096 Aug 14 11:53 sh
-rw-r--r-- 1 root root 977 Aug 14 22:43 ts
文件总大小:23231
sed
处理 行。
sed命令只要不加 -i 就不修改文件本身。
# a文件
id name gender mark
1 xyz male 90
2 lee female 78.22
3 lily female 99
sed [选项] '[动作]' 文件名
也可以接受管道符作为输入。
选项:
-n 表示只输出经过sed处理的内容,不加该参数,默认将所有数据输出到屏幕。
-i 修改文件本身。
-e 可以执行多条sed命令,命令直接用";"隔开。
动作:
p,打印某一行;a,行后追加;i,行前插入;c,整行替换;s,字符串替换;d,删除行。
在某一行后添加行(行前插入行),“\”表示还没结束,下面还有行。
执行:
sed -n '2p' a
结果:
1 xyz male 90
执行:
sed '2a nice \
good' a
结果:
id name gender mark
1 xyz male 90
nice
big
2 lee female 78.22
3 lily female 99
执行:sed '2s/xyz/taylor/g' a
结果:
id name gender mark
1 taylor male 90
2 lee female 78.22
3 lily female 99
执行:sed -e '2s/xyz/taylor/g ; 3s/lee/swift/g' a
若s前面不指定行,表示全部。
结果:
id name gender mark
1 taylor male 90
2 swift female 78.22
3 lily female 99
包含某字符串的行:/某字符串/
执行:
sed -n '/fe/p' a
结果:
2 swift female 78.22
3 lily female 99
打印一个范围的行
打印第3到第6行:sed -n '3,6p' a
行与行用逗号分隔。
打印从第几行到末尾: sed -n '开始行,$p' a
"$"代表末尾。
sort
排序
-r,反序
-f, 忽略大小写
sort 文件名
wc
wc 文件名
-l,只统计行数。
-w,只统计单词数。
-m,只统计字符数。
文件类型,权限判断
类型判断
-d 判断目录是不是存在。
-e 判断文件、目录是不是存在。
-f 判断普通文件是不是存在。
-L判断符号链接文件是不是存在。
权限判断
-r 判断文件是否存在,且有读权限,返回真。
-w 判断文件是否存在,且有写权限,返回真。
-x 判断文件是否存在,且有可执行权限,返回真。
两种判断格式:
test -e 文件名
[ -e 文件名 ] 注意 -e 前有空格,文件名 后有空格
判断两个文件的修改日期
- 文件1 -nt 文件2
文件1的修改日期比文件2的新,返回真。 - 文件1 -ot 文件2
文件1的修改日期比文件2的旧,返回真。
判断两个文件是不是同一个文件
根据inode号判断。
- 文件1 -ef 文件2
inode号一致,返回真。
整数比较
-eq
-ne
-gt
-lt
-ge
-le
字符串判断
-z 字符1 判断字符串1是不是为空,为空返回真。
-n 字符串1 判断字符串1是不是为非空,为非空返回真。
字符串1 == 字符串2 判断两个字符串是不是相等,相等返回真。
字符串1 != 字符串2 判断两个字符串是不是不相等,不相等返回真。
多重判断
判断1 -a 判断2 ,-a表示逻辑与。
判断1 -o 判断2 , -o表示逻辑或。
! 判断1, !表示逻辑非。
if结构
- if [ 条件 ]
then
....
fi - if [ 条件 ]
then
....
else
....
fi - if [ 条件 ]
then
....
elif [ 条件1 ]
then
....
elif [ 条件2 ]
then
....
....
else
....
fi
case结构
case $变量名 in
"值1")
....
;;
"值2")
....
;;
*)
若值都不是以上列出的情况,执行这里的。
....
esac
for结构
for i in {1..5}
do
echo $i
done
等价于
for (i=1;i<=5;i++)
do
echo $i
done
结果:
1
2
3
4
5
for i in xyz lee taylor
do
echo $i
done
结果:
xyz
lee
taylor
若我的dir目录下有3个文件:a,b,c
cd dir
ls > list 将ls命令的结果写入文件list,该文件自动以换行符分开。
for i in $(cat list) in后面的内容,以空格,换行符分开的,将视为一个元素。
do
echo $i
done
结果:
a
b
c
while结构
while [ 条件成立 ]
do
....
done
注意每次循环变量要改变,避免死循环。
until结构
until [ 条件不成立 ]
do
....
done
注意每次循环变量要改变,避免死循环。
函数
定义:
函数名(){
函数体
}
调用:
函数名
sleep
sleep 1 睡眠1秒
sleep 1s 睡眠1秒
sleep 1m 睡眠1分
sleep 1h 睡眠1小时
date
%后面分别接 Y, m, d, H, M, S
分别代表:年月日 时分秒
date +%Y%m%d
以数字形式显示年月日:20180814
date +%T
显示时分秒,以冒号分隔:23:41:07
date +%s
显示自1970-01-01 00:00:00 开始计算的秒数。
tar
tar,是一个打包,解包的工具,但他可以调用 bzip2 或 gzip 来一起使用。
bzip2:压缩率高,但要比gzip慢一点。
参数:(参数前的-可以省略)
-c:生成一个新文件。
-x:解包、解压。
-f:后面接包名或者文件名,有人说要放到最后,测试发现放哪里都一样。
-t : 显示包中的文件。
-r : 追加文件。
-u: 更新文件。
-z: gzip压缩或解压。
-j: bz2压缩或解压。
-J:xz压缩或解压。
-v: 显示过程。
-C:解压到指定目录。比如 : tar xzf aa.tgz -C /root/xyz
单纯打包:tar -cf 生成的包名.tar 要打包的文件名或者目录
解包:tar -xf 包名.tar
tgz和tar.gz其实是一样的
压缩:tar -czvf name.tar.gz(name.tgz) filename
解压:tar -xzvf name.tar.gz(name.tgz)
tar.bz2
压缩:tar -cjvf name.tar.bz2 filename
解压:tar -xjvf name.tar.bz2
tar.xz
压缩:tar -cJvf name.tar.xz filename
解压:tar -xJvf name.tar.xz
wget
一个下载工具
wget 下载地址
若给的url不是具体文件的话,将下载该网站首页的html页面。wget -i download.list
根据dowload.list中的地址下载,每个url记得换行。wget -O /path/name 下载地址
将文件下载到指定目录并重命名。wget -b 下载地址
在后台下载,并生成一个wget-log的日志文件。wget --spider 地址
测试是否能正常访问。