Bourne shell(sh) 、Bourne again shell(bash) C shell(csh)、Tenex C shell(tcsh)、Korn shell(ksh)
dash
1、格式
command [-options] [arguments]
ls -al /etc
mv a.txt b.txt
2、;和\
ps -elf | head -1;ps -elf | sort -rn -k3 | head -10
cat > a.txt << EOF
abc
efg
hij
EOF
cp -i \
a.txt \
b.txt
1、bash中常用通配符*,?,[ ]
。
*
匹配任意一个或多个字符
?
匹配任意单一字符
[ ]
匹配任意一个在方括号内的单字符
[123456],[1-6]
2、通配符组合使用
1、输入重定向<,<<
#计算行数,单词数,字符数
wc < /etc/passwd
wc << aa
abc
efg
aa
通知shell当前命令标准输入来自一对分隔符之间
2、输出重定向>,>>
ps -ef > ps.txt
#合并文件
cat file1 file2 file3 > file
>
不存在创建,存在覆盖。>>
不存在创建,存在后面追加3、错误重定向2>
或2>>
#正常屏幕上看到解压过程,如果包损坏错误信息输出到error.txt
tar zxvf text.tar.gz 2>error.txt
ls -al /etc | more
ps -ef | grep httpd | wc -l
#转义字符\放在特殊字符前,忽略特殊字符的原有含义
mv abc\?\* abc
#单引号' '字符串所有字符的特殊含义将被忽略
mv 'C:\backup' backup
#双引号" "字符串大部分特殊字符当作普通字符处理,但$、\、`仍保留特殊含义
str="the \$shell current shell is $shell"
echo $str
tar、gzip、gunzip、bzip2、bunzip2
1、文档归档并压缩解压命令tar
-c,-x,-t,-r,-u
-z,-j,-v,-f,-p,-w,-Z,-N "yyyy/mm/dd", -exclude file
tar -cvf /opt/etc.tar /etc
tar -zcvpf /opt/etc.tar.gz /etc
tar -jcvf /opt/etc.tar.bz2 /etc
tar -ztvf /opt/etc.tar.gz
tar -zxvf /opt/etc.tar.gz etc/inittab
tar -jtvf /opt/etc.tar.bz2
#第一f后面的-将创建的文件输出到标准输出上
#第二f后面的-从标准输入中读取数据
tar -zcvf - /etc | tar -zxvf -
#自动备份脚本
#!/bin/sh
#变量
days=7 #本地备份文件保留天数
user=laaos # 本地用户名
remoteuser=tsmem # 远程备份机用户
datetime=`date +%Y_%m_%d` #备份日期
baksrcdir=/db/mysql/data #需要备份的文件
bakupdir=/data/backupdata #本地备份文件存放目录
bakdata=${user}_${datetime}.tar.gz #备份文件名称
baklog=${user}_${datetime}.log #备份日志
remoteIP=192.168.23.130 #远程备份机地址
remotePath=/backupdata/dbdata #远程备份文件存放路径
#备份
#进入备份文件将存放目录
cd ${bakupdir}
#判断是否存在以用户命名的文件夹,如果不存在创建
if [ ! -d "${user}" ];then
mkdir "${user}"
fi
#进入以用户命名的文件夹
cd ${user}
#向日志文件写入日期和具体时间
echo "backup start at ${datetime} `date`" > ${baklog}
echo "-----------------------" >> ${baklog}
#备份数据和日志
tar -zcvf ${bakdata} ${baksrcdir} ${baklog}
#删除本地日志文件
find ${bakupdir}/${user} -type f -name "*.log" -exec rm {} \;
#删除本地超过保存天数的备份文件
find ${bakupdir}/${user} -type f -name "*.tar.gz" -mtime +$days -exec rm {} \;
#备份到远程
rsync -avzPL -e "ssh -i /home/laaos/.ssh/id_rsa" ${bakupdir}/${user}/${bakdata} ${remoteuser}@${remoteIP}:${remotePath}
#本地机器和远程备份机的无密码登陆操作
#ssh-keygen参数说明
#-b bits 指定要创建的秘钥中的位数,默认 2048 位。值越大,密码越复杂
#-C comment 注释,在 id_rsa.pub 中末尾
#-t rsa/dsa等 指定要创建的秘钥类型,默认为 RSA
#-f filename 指定公私钥的名称,会在 $HOME/.ssh 目录下生产私钥 filename 和公钥 filename.pub
#-N password 指定使用秘钥的密码,使得多人使用同一台机器时更安全
#方式一
#本地机器操作操作
ssh-keygen -t rsa
scp /usr/rsync_id_rsa.pub [email protected]:/home/remoteuser/.ssh
#远程备份机操作
cat rsync_id_dsa.pub >> authorized_keys
chown remoteuser:remoteuser authorized_keys
方式二
# 生成公私钥,默认文件为 ~/.ssh/id_rsa
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# 发送公钥的两种方式(等价)
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
#管理秘钥
#ssh-agent 和 ssh-add 是安全外壳(SSH)协议套件的标准组件,用于管理私钥。
#一般情况下我们使用不带密码的 id_rsa 作为我们的默认私钥,此时是没必要启动 ssh-agent 的。
#当我们碰到以下两种情况则需要它:
#1,使用不同的秘钥连接到不同的主机时,需要手动指定对应的秘钥。(ssh-agent 帮我们选择对应的秘钥进行认证)
#2,当私钥设置了密码,而我们又需要频繁的使用私钥进行认证。(ssh-agent 帮我们免去重复输入密码)
#代理常用命令
# 启动代理
eval `ssh-agent`
# 关闭代理
ssh-agent -k
# 在 ~/.bashrc 中加入以下来实现登陆自动启动 ssh-agent,退出自动 kill 掉程序
eval $(ssh-agent -s) > /dev/null
trap 'test -n "$SSH_AGENT_PID" && eval `/usr/bin/ssh-agent -k` > /dev/null' 0
# 查看代理中的私钥
ssh-add -l
# 查看代理中私钥对应的公钥
ssh-add -L
# 移除指定的私钥
ssh-add -d /path/of/key/key_name
# 移除所有的私钥
ssh-add -D
#保证/etc/ssh/sshd_config文件中“AuthorizedKeysFile .ssh/authorized_keys”语句未被注释
#不希望输入IP,保证/etc/hosts文件存在“IP HOST”
#ssh-keygen -t rsa生成秘钥(id_rsa和id_rsa.pub)存在~/.ssh文件夹中
#将公钥写入证书
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
ssh root@node02 cat /root/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
#将证书拷贝到其他机器
scp ~/.ssh/authorized_keys root@node02:/root/.ssh/authorized_keys
#一台本地主机需要维护多台远程服务器的话,如果生成多个公钥密钥对的话本地文件肯定重名,怎么办呢!?
#其实公钥之所谓公钥,就是公开的密钥,只需要在本地生成一对公钥私钥然后将公钥分别放在多台远程服务器上就行了!
正确做法
ssh UserB@ServerB 'echo "hello world" > index'
没错,只是单纯的用引号将命令括起来就行了,这样会被当做位置参数传递给ssh,然后就能成功在远程机上运行了
#!/bin/bash
#多进程对多个机器同时发指令
#注意下面的用户和ip是一一对应的,顺序不要搞错,额否则不能登录
#user1登录server1
server=(
"192.168.1.1"
"192.168.1.2"
"192.168.1.3"
"192.168.1.4"
)
user=(
"test1"
"test2"
"test3"
"test4"
)
#服务器和用户账号对应关系
tot_s=${#server[*]}
tot_u=${#user[*]}
if [ $tot_s -ne $tot_u ];then
echo "服务器和用户账号数量不对应,请检查server列表和user列表"
exit
fi
i=0
while [ $i -lt $tot_u ];do
(ssh ${user[$i]}@${server[$i]} "command1;command2" & ) 2>> ~/Desktop/log.txt
#注意一定要在最后面加&符号,否则就是串行执行,不能体现并行。
#将错误重定向到日志文件中
if [ $? -ne 0 ];then
echo "${user[$i]}@${server[$i]}执行过程中出现异常"
fi
#注意迭代器别忘了自增
i=$[ $i + 1 ]
done
2、文件压缩解压命令gzip/gunzip
-d,-r,-t,-v,-l,-num
gzip -d等价gunzip
3、文件压缩解压命令bzip2/bunzip2
-k保留原始文件
,-f覆盖同名文件
,-压缩级别
1、强大的文件查找命令find
find pathname -options -print -exec command {} \;
-mtime +-
,-type bcfldps,
#\ 表示不由shell解释为特殊字符,而由find命令区解释其意义
find / \( -path /var/log -o -path /usr/bin \) -prune -o -name "a.txt" -print
2、给其他命令传递参数的过滤器命令xargs
touch {1..9}.txt
xargs将管道传来的数据当作命令行参数
-p交互式询问,-d @指定分隔符,
-n 3一次性传递3个参数,
find . -name "*.txt" | xargs -i -t rm -rf {}
#文件名有空格的删除
#更广泛
find -name "* *.log" -prnt0 | xargs -0 rm -rf
#更通用型非find命令(如ls)也行
find -name "* *.log" | xargs -i rm -rf "{}"
ls | grep ". ..log" | xargs -i -rm -rf "{}"
#文件连接命令join
join -t ':' -1 3 file1 -2 3 file2
#合并文件命令paste
cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
#文件排序命令sort
cat /etc/passwd | sort -t ':' -k3 -rn | head -n 10
#head 等价于 head -10
#检查并删除文件重复行命令uniq
sort file | uniq -d -c
for pid in $(ps -ef | grep -v grep | grep java | awk '{print $2}')
do
echo ${pid} >/tmp/a.txt
cat /proc/${pid}/status | grep Threads >/tmp/b.txt
paste /tmp/a.txt /tmp/b.txt
done | sort -k3 -rn
ps -e -o stat,ppid,pid,cmd | grep -e '^ [Zz]' | awk '{print $2}' | xargs -i kill -9
#获取当前系统占用CPU最高的前10个进程
ps aux | head -1;ps aux | sort -rn -k3 | head -10
#获取当前系统占用内存最高的前10个进程
ps aux | head -1;ps aux | sort -rn -k4 | head -10
#使用wget下载单个文件并使用--limit-rate参数进行限速下载
wget --limit-rate=1M http://mirror.163.com/centos/7.6.1.1810/isos/x86_64/Centos-7-x86_64-DVD-1810.iso
#使用wget -c断点续传
wget -c http://mirror.163.com/centos/7.6.1.1810/isos/x86_64/Centos-7-x86_64-DVD-1810.iso
#测试服务器是否支持断点续传
#执行结果出现Accept-Ranges:bytes说明服务器支持短点续传下载
wget -S http://mirrors.163.com 2>&1 | grep "Accept-Ranges"
#使用wget下载文件以不同的文件名保存(一般以最后一个/后面的字符命名)-O指定一个文件名
wget -O php-7.3.2.tar.bz2 http://cn2.php.net/get/php-7.3.2.tar.bz2/from/this/mirror
#通过curl显示网站的header信息
curl -I http://www.baidu.com
#显示网站的http状态代码,-w输出一些定义的元数据
#http_connect,time_total,time_connect,time_appconnect,time_redirect,
#size_download,size_upload,content_type,ssl_verify_result
curl -s -o /dev/null -w %{http_code} "\n" http://www.baidu.com
#使用curl实现URL地址重定向,-L自动地址重定向
curl -L -I http://www.baidu.com
#抓去网页内容并保存到本地
curl -O http://www.baidu.com/default.htm
curl -o test.htm http://www.baidu.com/default.htm
通过curl下载文件并开启断点续传,宽带限速,-C实现断点续传,-C-实现自动续传
curl --limit-rate 2M -C- -O http://www.baidu.com/mirror.iso
#远程复制到本地
scp RemoteUser@IP:RemoteAbsolutePath/file LocalPath
#本地复制到远程
#默认端口22,-P指定端口; cp -r与scp -r含义一致,-l 1000限速单位Kbit/s
scp -r -P 1022 -l 10000 LocalPath/file RemoteUser@IP:RemoteAbsolutePath
#第一部分路由信息Host
#第二部分丢包率Loss%(丢包可能是ICMP保护机制),发送数据包数量`Snt`
#第三部分Last,Avg,Best,Wrst,StDev最后一次,平均,最小,最大,标准偏差包延迟
yum install mtr
mtr 192.168.23.13
1、什么是正则表达式(Regular Expression,RE)
2、正则表达式组成由一下一项或多项
锚(^和$)
——正则表达式所匹配文本在文本行所处位置修饰符(*星号、<>[]{}括号、\反斜杠)
——扩大或缩小正则表达式匹配文本的范围*
匹配前面一个普通字符的0次或多次重复.
匹配任意一个字符^
匹配行首或后面字符的非$
匹配行尾^$
匹配空白行[]
匹配字符集合中某一个字符\
转义符,屏蔽一个元字符的特殊意义\<\>
精确匹配符号\{n\}
匹配前面字符出n次\{n,\}
匹配前面字符至少出n次\{n,m\}
匹配前面字符出n次m次之间[xyz],[c-n],[B-Pk-y],[a-z0-9],[\^b-d],[Yy][Ee][Ss]
[a-z]\{5\}匹配5个小写英文字母
1、变量的定义与分类
用户自定义变量
——用户自定义,修改和使用shell环境变量PATH
——设置用户shell工作环境,少数用户修改其值位置参数变量(Positional Parameters)
——命令行给程序传递执行参数,shift命令实现位置参数的迁移内部参数变量(Special Parameters)
——bash预定义的特殊变量,用户不能修改其值2、变量的赋值
$
变量替换符号,variable变量名,$variable变量值
#变量赋值
variable=value
variable=`command argument`
数字、字母、下划线,数字不能作为开头
3、变量的声明和使用
shell变量是弱变量不用声明类型
(等号两边不能有空格)
#变量引用
#一个字符的变量名
$variable
#多个字符变量名
${variable}
4、变量的清除和只读
变量设置为只读,用户将不能对此变量重新赋值和清除
variable=value
readonly variable
5、内部参数变量
内部参数变量及含义
$@
表示传递给脚本或函数的所有参数。被双引号"“包含时,所有参数仍然分开$1、$2输出。
$*表示传递给脚本或函数的所有参数。当被双引号”"包含时,所有参数作为一个整体$1$2输出。
$0
命令行上输入的shell程序名
$#
命令行上参数的个数
进程相关内部参数
$?
表示上一条命令执行后的返回结果
$$
表示当前进程号
$!
显示运行在后台的最后一个作业的pid
$_
表示之前执行的命令或脚本的最后一个参数
内部域分隔符IFS(Interal Field Seperator)默认值值为空白(空格、Tab和新行)
#IFS转化八进制
echo "$IFS" | od -b
#040是空格,011是Tab,012是换行符
“$*“会根据IFS不同来组合值,$@、”$@”、$*会将值用空格来组合值,推荐使用$@
6、位置参数变量
$1
表示第1个参数,${10}
表示第10个参数(10开始参数号需要用大括号括起来)7、退出/返回状态(0:成功;1-255:失败)
0
执行正确或成功1
通用错误或执行失败124
网络不通126
命令或脚本没有执行权限127
命令没找到8、命令替换(抽取一个命令的输出)
#命令替换两种形式
`linux_comman`
$(linux_command)
9、read命令(接受键盘输入内容为变量赋值)
#read例子
#读取变量给variable
read variable
#同事读取多个变量
read x y
#自动从键盘读取输入内容,并复制给REPLY变量
read
#自动从键盘读取输入内容,并复制给REPLY变量,并给出输入提示
read -p "please input:"
结合不同引号为变量赋值
1、变量测试的用法(shell支持变量测试和默认赋值)
#变量测试几种用法和含义
#var存在且非空,值为$var;var未定义或为空,测试值为word,var值不变。
${var:-word}
#var存在且非空,值为$var;var未定义或为空,测试值为word,var赋值word。
${var:=word}
#var存在且非空,值为$var;var未定义或为空,输出信息word,中止脚本。
${var:?word}
#var存在且非空,值为word;否则返回空值,var值不变。
${var:+word}
2、字符串长度和截取(awk和sed文本字符串过滤、筛选、替换,shell也支持此功能)
#字符串长度与截取的用法与含义
#返回字符串变量var长度
${#var}
#返回${var}中从m个字符之后的所有部分
${var:m}
#返回${var}中从m个字符之后开始,长度为len的部分
${var:m:len}
#删除${var}中开头部分与pattern匹配的部分
${var#pattern}
#删除\${var}中结尾部分与pattern匹配的部分
${var%pattern}
#用new替换${var}中第一次出现的old
${var/old/new}
#用new替换${var}中所有的old(全局替换)
${var//old/new}
#用new替换${var}中开头部分与old匹配的部分
${var/#old/new}
#用new替换${var}中结尾部分与old匹配的部分
${var/%old/new}
3、变量的间接引用
str="hello world"
str1=str
echo ${ ! str1 }
eval echo \$$str1
4、同时输出多行信息
echo "
line
line0
lne1
"
#END为任意字符串
cat << END
line
line0
lne1
END
1、算数运算扩展(运算数只能是整数)
$[expression]
$((expression))
((num=2+3**2-1001%5));echo $num
num=$((2+3**2-1001%5));echo $num
echo $((2+3**2-1001%5))
echo $((a+b*c))
echo $(( $a + $b * $c ))
#同理$[???]
((a++)),((a--))
2、算术运算指令expr
(数值运算、数值或字符串比较、字符串匹配、字符串提取、字符串长度计算等功能;
判断变量或参数是否为整数、是否为空、是否为零等)
表达式中参数和操作符必须以空格分开,乘法符号和括号必须被转义
expr 5 % 3
expr 5 \* 3
expr \( 2 + 5 \) \* 2 - 6
3、算术运算指令let
let是bash的内部命令
,从左到右顺序给每一个参数进行算术运算;最后一个参数求值结果为真返回退出码0,否则返回1
;默认情况下任何操作符两边不能留空格
;所有算术表达式连接在一起,使用空格时需要用双引号将表达式括起来
)赋值符号和运算符两边不留空格,字符串赋值给整型变量时变量值为0,变量值是字符串进行算术运算时设为0
#let进行算术运算时最好加双引号
let "num=4 + 1"
4、自增自减运算符
(++variable)
、前置自减(--variable)
首先改变变量,再将变量交给表达式使用(variable++)
、后置自减(variable--)
表达式使用过后再改变变量的值1、条件测试
命令成功或失败、表达式为真或为假;
查找当前用户是否存在
grep $USER /etc/passwd
#结果为0,表示用户存在
echo $?
2、test与条件测试语句
* test
命令在shell中主要用于条件测试,返回0值为真,返回大于0值为假;
test命令支持测试的范围包括字符串比较、算术比较、文件是否存在、文件属性和类型判断等
shell中条件测试语法格式有三种:
test expression
完全等价[expression]
基本等价于[[expression]]
bash2.x版本以上&支持更多表达式:&&、||、!、()
。
单双中括号内左右两边必须有空格
整数进行关系运算,还可用(( ))。(( ))进行整数测试,其中变量前缀$可有可无
条件测试表达式中常见操作符
字符串测试操作符、整数比较操作符、逻辑运算符、文件测试操作符
#test命令测试表达式的值
x=8; y=12; test $x -gt $y; echo $? #值为1假
x=8; y=12; test $x -lt $y; echo $? #值为0真
x=8; y=12; [ $x -gt $y ]; echo $? #值为1假
x=8; y=12; [ $x -lt $y ]; echo $? #值为0真
3、方括号测试表达式
[[ ]]基本等价于[ ]
,功能写法更简洁,且提供正则表达式
,[[ ]]功能
可认为是test和expr命令的相加
通配符
进行模式匹配name=Tom; [ $name = [Tt]?? ]; echo $? #值为1假,[ ]不支持通配符
name=Tom; [[ $name = [Tt]?? ]]; echo $? #值为0真,[[ ]]支持通配符
4、字符串测试操作符
比较两个字符串是否相同、字符串长度是否为零、字符串是否为NULL
#字符串测试操作符及含义(单双中括号两边必须留空格)
#如果字符串str长度为0,返回真
[ -z str ]
#如果字符串str长度不为0,返回真
[ -n str ]
#如果字符串str不为空,返回真
[ str ]
#测试字符串str是否与字符串str0相等,可使用==代替=
[ str = str0 ]
#测试字符串str是否与字符串str0不相等,可使用!==代替!=
[ str != str0 ]
#两个字符串相同返回真
[[ str == str0 ]]
#两个字符串不相同返回真
[[ str != str0 ]]
#str0是str子串返回真
[[ str =~ str0 ]]
#str>str0返回真
[[ str > str0 ]]
#str
[[ str < str0 ]]
#字符串中有空格,进行字符串长度是否为0判断时,将变量加上双引号,命令正常执行。
name="Tom sql"; [ -z "$name" ]; echo $?
#总结:字符串或字符串变量比较,都加双引号;字符串或字符串变量比较,比较符号两端都有空格;
#=比较两个字符串是否相等,与==等价,最好办法
[ "${s}" = "${b}" ]
#检查字符串是否为空
[ "$name" = "" ],[ -z "$name" ],[ ! "$name" ],[ "X${name}" = "X" ]
#检查字符串是否为非空值
[ "$name" != "" ],[ -n "$name" ],[ "$name" ],[ "X${name}" != "X" ]
5、逻辑测试操作符
逻辑非、与、或
)[ expr -a expr0 ] #逻辑与,都为真时,结果为真
[ expr -o expr0 ] #逻辑或,有一个为真时,结果为真
[ ! expr ] #逻辑非
#例子(不能在中括号中随意添加小括号)
x=1; name=tom; [ $x -eq 1 -a -n $name ]; echo $?
#匹配模式的逻辑测试操作符及含义(只能在双中括号中,不能在单中括号中)
[[ pattern && pattern0 ]] #逻辑与
[[ pattern || pattern0 ]] #逻辑或
[[ ! pattern ]] #逻辑非
#匹配模式的逻辑测试表达式支持通配符
x=1; name=Tom; [[ $x -eq 1 && $name = To? ]]; echo $?
6、整数测试操作符(整数测试即比较大小)
#整数测试操作符与含义
[ int -eq int0 ]#int等于int0
[ int -nq int0 ]#int不等于int0
[ int -gt int0 ]#int大于int0
[ int -ge int0 ]#int大于或等于int0
[ int -lt int0 ]#int小于int0
[ int -le int0 ]#int小于或等于int0
[[ int -eq int0 ]]#int等于int0,返回真
[[ int -nq int0 ]]#int不等于int0,返回真
[[ int -gt int0 ]]#int大于int0,返回真
[[ int -ge int0 ]]#int大于或等于int0,返回真
[[ int -lt int0 ]]#int小于int0,返回真
[[ int -le int0 ]]#int小于或等于int0,返回真
#整数测试操作符中,单双中括号对应操作符两边必须留空格;比较的只能是整数。
#双小括号的整数测试操作符与含义,双小括号操作符两边的空格可以省略
((int == int0))int等于int0,返回真
((int != int0))int不等于int0,返回真
((int > int0))int大于int0,返回真
((int >= int0))int大于或等于int0,返回真
((int < int0))int小于int0,返回真
((int <= int0))int小于或等于int0,返回真
#==,!=,<,>操作符也可用在单双中括号中,只不过<和>符号在[ ]中使用需要转义
7、文件测试操作符(测试文件是否存在、文件属性、访问权限
等场景)
#文件测试操作符与含义
[ -f fname ] #fname存在且是普通文件时,返回真(即返回0)
[ -L fname ] #fname存在且是链接文件时,返回真
[ -d fname ] #fname存在且是一个目录时,返回真
[ -e fname ] #fname(文件或目录)存在时,返回真
[ -s fname ] #fname存在且大小大于0时,返回真
[ -r fname ] #fname(文件或目录)存在且可读时 ,返回真
[ -w fname ] #fname(文件或目录)存在且可写时,返回真
[ -x fname ] #fname(文件或目录)存在且可执行时,返回真
8、条件测试举例
#值为0,命令中&&并非逻辑运算符,而是命令聚合符号
x=6; name=iivey; (( $x == 6 )) && [[ $name = iive? ]]; echo $?
#值为1,字符串变量作比较,变量最好用双引号括起,方括号内前后留空格,[ ]内不能使用通配符
name=tom; name0=ivvey; [ "$name" = "$name0" ]; echo $?
#结果为假,整数测试,双小括号中可以加上变量前缀\$,也可以省略\$,对执行结果不影响
n=5; m=7; ((n>m)); echo $?和n=5; m=7; (($n>$m)); echo $?
#结果为假,整数测试
n=5; m=7; [[ $n>$m ]]; echo $?
#结果为真,去掉$后变成了字符串测试大小,这里比较n和m对应的ASCII码大小
n=5; m=7; [[ n>m ]]; echo $?
#结果为T,…&&…||…第一句为真,输出第二句;第一句为假,输出第三句
a=linux; b=unix; [ $a != $b ] && echo T || echo F
1、简单if结构
#简单
if expression
then
command
fi
#或者
if expression; then
command
fi
2、if/else结构
#普通
if expression
then
command
else
command
fi
#嵌套
if expression
then
if expression
then
command
else
command
fi
else
command
exit
fi
3、if语句执行流程
if-then-fi
if-then-else-fi
4、if/elif/else结构
if-then-(elif-then)-…else-fi,
elif expression; then
5、使用if/else判断注意事项
if语句必须以if开头,以fi结尾
elif可以任意多个(0个或多个)
else最多只能有1个(0个或一个)
command为可执行语句块,如果为空,需要使用shell提供的空命令:,即冒号。
1、语法结构
case expr in
pattern)
commands
;;
pattern0)
commands0
;;
…
*)
commands1
;;
esac
2、case语句的几点说明
一旦有模式匹配成功,则执行该模式后面的所有命令,然后退出case
。如果expr没有找到匹配模式,则默认执行*)后面的命令块(类似if中的else)可以不出现
。通配符和|
每个命令块的最后必须有一个双分号,可以独占一行,或放在最后一个命令的后面
1、列表for循环
#列表for循环语法结构
for variable in list
do
commands
done
list列表中带有空格的列表项,必须用双引号括起来作为一个整体
$x和eval $x的区别:$x打印命令,eval $x执行命令
2、不带列表for循环
不带列表的for循环执行是由用户指定参数和参数的个数
#不带列表的for循环的基本格式
for variable
do
command
command
done
#或者
for variable; do
command
command
done
#不带列表的for循环其实是使用了位置参数$@来传递for中的list列表,for循环省略了in $@关键字
3、for循环举例
#使用文件名或目录名列表作为list,*表示当前目录下的文件和目录
#! /bin/bash
for fname in *; do
fn=$(echo $fname | tr A-Z a-z)
if [[ $fname != $fn ]]; then mv $fname $fn; fi
done
#使用命令的执行结果作为list的for循环,awk -F '{print $1}'被反单引号包括
#! /bin/bash
i=1
for username in awk -F '{ print $1}' /etc/passwd
do
echo "Username $((i++)) : $username"
done
for suffix in $(seq 10)
do
echo "192.168.23.${suffix}"
done
#使用命令替换符的结果作为list
#! /bin/bash
for host in $(cat /etc/hosts)
do
if ping -c 1 -w 2 $host &>/dev/null
then
echo "Host ($host) is active."
else
echo "Host($host) is Down."
fi
done
#使用数值范围作为list,{1..10}和$(seq 10)表示分别读取一到十中的数,{1..10..2}表示分别每隔两个步长读取一到十中的数
#! /bin/bash
mynet="192.168.0"
for num in {1..6}
do
echo "ip address is ${mynet}.$num"
done
for num in {1..10..2}
do
echo "Number: $num"
done
#批量添加10个linux系统用户,stdin是接受后面的字符串作为密码,stdin表示非交互直接传入密码;
#passwd默认终端作为标准输入,加上- -stdin表示可以用任意文件作为标准输入,于是这里用管道作为标准输入;
#chage命令强制新用户第一次登陆时修改密码
#! /bin/bash
for x in {1..10}
do
useradd user${x}
echo "Centos" | passwd --stdin user${x}
chage -d 0 user${x}
done
4、break和continue
break强制退出当前循环,如果嵌套循环break命令后可跟一数字n,表示退出第n重循环(最里面的为第1重循环)
break [n]
continue用于忽略本次循环的剩余部分,回到循环顶部,继续下一次循环,如果嵌套循环continue命令后也可跟一数字n,表示回到第n重循环的顶部
continue [n]
#break例子
#! /bin/bash
i=1
for day in Mon Tue Wed Thu Fri
do
echo "Weekday $((i++)): $day"
if [ $i -eq 3 ]; then
break
fi
done
#continue例子
#! /bin/bash
i=1
for day in Mon Tue Wed Thu Fri Sat Sun
do
echo -n "Day $((i++)): $day"
if [ $i -eq 7 -o $i -eq 8 ]; then
echo " (WEEKEND)"
continue
fi
echo " (weekday)"
done
5、for循环(C语言)语法
执行expr1;若expr2的值为真进入循环,否则退出for循环;
执行循环体,之后执行expr3,然后判断expr2的值,为真继续循环;循环结束标志,返回循环顶部。 expr1和expr3为算术表达式,expr2为逻辑表达式,
类C风格的for循环也被称为计次循环
,一般用于循环次数已知的情况。expr1为循环变量赋初始值,expr2是否循环的表达式,expr3改变循环变量的语句
。for ((expr1;expr2;expr3))
do
commands
done
#例子批量新建linux系统用户
for (( n=1; n<=50; n++ ))
do
if ((n<10))
then st="st0${n}"
else st=st${n}
fi
useradd user${n}
echo "Centos" | passwd --stdin user${n}
chage -d 0 user${n}
done
1、循环语句
while expr
do
commands
done
2、while循环语句执行流程
3、while循环例子
#最基本的while循环
#! /bin/bash
num=$((RANDOM%100))
while :
do
read -p "please guess my number [0-99]:" answer
echo $num
if [ $answer -lt $num ]
then
echo "inputed number less than my number"
elif [[ $answer -gt $num ]]; then
echo "inputed number greater than my number"
elif ((answer=num)); then
echo "ok! congratulation:my number is $num"
fi
done
#! /bin/bash
while IFS=: read -r user enpass uid gid desc home shell
do
[ $uid -ge 500 ] && echo "User $user $enpass ($uid) $gid $desc assigned "$home" home directory with $shell shell."
done </etc/passwd
#! /bin/bash
cat /etc/resolv.conf | while read line
do
echo $line
done
#! /bin/bash
file =/etc/resolv.conf
while IFS= read -r line
do
echo $line
done < "$file"
#! /bin/bash
DIR="."
find $DIR -type f | while read file; do
echo $file
if [[ "$file" = *[[ :space: ]]* ]]; then
mv "$file" $(echo $file | tr ' ' '_')
fi
done
#! /bin/bash
#counter计数器结构
counter=1
while expression
do
command
...
let command to operate counter
done
#counter计数器例子
counter=1
while [ $counter -lt 10 ]; do
let "count+=1"
echo $counter
done
5、结束标记控制的while循环
#! /bin/bash
#结束标记控制结构
read variable
while [[ "$variable" != sentinel ]]
do
read variable
done
#结构标记控制例子
#! /bin/bash
echo -e "please input values"
read variable
while [[ "$variable" != OK ]]; do
read varible
echo $variable
done
6、标志控制的while循环
#标志控制结构
#! /bin/bash
signal=0
while (( signal != 1 ))
do
...
if expressioin
then
signal=1
fi
...
done
* 如果执行时没带参数OK就会一直循环
#! /bin/bash
signal=0
while (( signal != 1 ))
do
if [[ $@ = ok ]]; then
signal=1
fi
done
1、
#until循环的语法
#! /bin/bash
until expr
do
commands
done
2、until循环执行流程:条件不成立执行循环体
3、until循环举例
#循环将ping通IP,再ssh连接操作
#!/bin/bash
read -p "Enter IP Address:" ipadd
echo $ipadd
until ping -c 1 $ipadd $> dev/null
do
sleep 60
done
ssh $ipadd
#exit用于推出脚本或当前进程
#sleep主要实现休眠指定的时间 sleep 1等价sleep 1s表示暂停1s
#sleep 1m表示暂停1分钟;sleep 1h表示暂停1小时
#! /bin/bash
username=$1
if [ $# -lt 1 ]; then
echo "Usage: `basename $0` []"
exit 1
fi
if grep "^$username:" /etc/passwd >/dev/null; then :
else
echo "$username is not a user in the system."
exit 2
fi
until who | grep "$username" > /dev/null; do
echo "$username is not logged on."
sleep 5
done
while与case配合可以实现菜单循环;bash提供了select循环。
#! /bin/bash
PS3="What is your prferred scripting language "
select s in bash perl python ruby quit
do
case $s in
bash|perl|python|ruby) echo "You selected $s" ;;
quit) exit ;;
*) echo "You selected error,retry..." ;;
esac
PS3= "What is your preferred OS?: "
IFS='|'
os="Linux|Gnu Hurd|FreeBSD|Mac OS X"
select s in $os
do
case $REPLY in
1|2|3|4) echo "You selected $s" ;;
*) exit ;;
esac
done
PS3="Select a program you want to execute: "
TOPLIST="telnet htop atop nettop jnettop iftop ftop iotop mytop innotop dnstopap achetop"
select prog in $TOPLIST quit
do
[[ $prog == quit ]] && exit
rpm -q $prog > /dev/null && echo $prog || echo "$prog is not installed. "
done
alias F='/user/sbin/nginx'
F
ps -ef | grep nginx
function fname{
command
[return]
}
functionname() {
commands
}
#! /bin/bash
function pws() {
echo "i am the best"
}
function idnim() {
echo "to be better"
}
pws
idnim
1、函数的调用
#! /bin/bash
function show() {
echo "hello,you are calling the function "
}
echo "first time call the function"
show
echo "second time call the function"
show
#user defnie function
sql_bak() { echo "Running mysqldump tool ..."; }
sync_bak() { echo "Running rsync tool ..."; }
git_bak() { echo "Running gistore tool ..."; }
tar_bak() { echo "Running tar tool ..."; }
PS3="Please choose a backup tools: "
select s in mysqldump rsync gistore tar quit; do
case $REPLY in
1) sql_bak ;;
2) sync_bak ;;
3) git_bak ;;
4) tar_bak ;;
5) exit ;;
esac
done
2、函数的存储
3、函数的显示
declare -F
declare -f function
unset -f
export -f
$1,$2,${n},$*,$@
表示其接受的参数,调用结束之后都将被重置为调用函数之前的值1、函数中参数的传递规则
#! /bin/bash
function show() {
echo "hello, youare calling the function $1"
}
echo "first time call the function "
show first
echo "second time call the function"
show second
#! /bin/bash
# 脚本内函数调用,脚本外通过位置参数传递值给函数
# 内部函数之间的互相调用
echo "====Print positional paramters in main :"
echo "$0: $*"
pp1(){
echo 'f1--Print $* parameters in fun1 :'
echo "$0:$*"
}
pp2(){
echo 'f2--Print $* parameters in fun1 :'
echo "$0:$*"
pp1 1rt 2nd 3th 4th 5th 6th 7th 8th 9th
echo 'f2--Print $*parameters in fun1 :'
echo "$0:$*"
}
pp1 1 2 3 4 5 6 7 8 9
echo "===Print positional parameters in main :"
echo "$0:$*"
pp2 I II III IV V VI VII VIII IX
#! /bin/bash
usage(){
echo "List the MAX of the positive integers in command line. "
echo "Usage: `basename $0` ..."
exit
}
max(){
[[ -z $1 || -z $2 ]] && usage
largest=0
for i; do ((i>largest)) && largest=$i; done
max "$@"
echo "The Largest of the numbers is $largest"
}
2、函数的结果和返回值
#! /bin/bash
function abc(){
RESULT=`expr $1 \% 2`
if [ $RESULT -eq 0 ]; then
return 0
else
return 1
fi
}
echo "Please enter a number who can devide by 2"
read N
abc $N
case $? in
0)
echo "yes,it is"
;;
1)
echo "no,it is not"
;;
esac
#! /bin/bash
# 比较两个数字的大小
# return只能返回0-256之间的整数,超过大小的数字比较会报错
max(){
if [[ -z $2 ]] || [[ -z $2 ]]; then
echo "Need two paramters to the function."; exit
fi
[ $1 -eq $2 ] && { echo "The two numbers are equal."; exit; } || (($1>$2)) && return $1 || return $2
}
read -p "Please input two integer numbers : " n1 n2
echo "n1=$n1,n2=$n2"
max $n1 $n2
return _val=$?
echo "The larger of the two numbers is $return_val."
# sh -x 脚本名称,查看脚本文件执行过程
#改进版本的数值比较
max(){
if [[ -z $2 ]] || [[ -z $2 ]]; then
echo "Need two paramters to the function."; exit
fi
largest=0
[ $1 -eq $2 ] && { echo "The two numbers are equal."; exit; } || (($1>$2)) && largest=$1 || largest=$2
}
read -p "Please input two integer numbers : " n1 n2
echo "n1=$n1,n2=$n2"
max $n1 $n2
echo "The larger of the two numbers is ${largest}."
3、分离函数体执行函数的脚本文件
#! /bin/bash
cat >>/etc/init.d/function<<EOF
function warrior(){
echo "i am warrior"
}
EOF
#代码导入/etc/init.d/function文件中,这个文件成为Linux系统内置的脚本函数库,按照下面方式调用
#分离函数执行体的功能,系统自带一些脚本中经常用到
if [ -f /etc/init.d/function ]
then
. /etc/init.d/function
fi
warrior
#! /bin/bash
running=0
sleeping=0
stoped=0
zombie=0
for pid in /proc/[1-9]*
do
procs=$[procs+1]
stat=$(awk '{print $3}' $pid/stat)
case $stat in
R)
running=$[running+1]
;;
T)
stoped=$[stoped+1]
;;
S)
sleeping=$[sleeping+1]
;;
Z)
zombie=$[zombie+1]
;;
esac
done
echo "进程统计信息如下: "
echo "总进程数量为:$procs"
echo "Running进程数为:$running"
echo "Stoped进程数为:$stoped"
echo "Sleeping进程数为:$sleeping"
echo "Zombie进程数为:$zombie"
# 学习编写shell脚本的逻辑和思路,这个思路可以编写多个服务器状态的监测脚本
#! /bin/bash
partition_lsit=(`df -h | awk 'NF>3&&NR>1{sub(/%/,"",$(NF-1));print $NF,$(NF-1)}'`)
critical=90
notificaton_email()
{
emailuser='[email protected]'
emailpasswd='password'
emailsmtp='smtp.domain.com'
sendto='[email protected]'
title='Disk Space Alarm'
/usr/local/sendEmail-v1.56/sendEmail -f $emailuser -t $sendto -s emailsmtp -u $title -xu $emailuser -xp $emailpasswd
}
crit_info=""
for(i=0;i<${#partition_list[@]};i+=2)
do
if [ "${partiton_list[((i+1))]}" -lt "$critical" ]; then
echo "OK ${partition_list[i]} used ${partition_list[((i+1))]}%"
else
if [ "partition_list[((i+1))]" -gt "$critical" ]; then
crit_info=$crit_info"Warning!!! ${partition_list[i]} used ${partition_list[((i+1))]}%\n"
fi
fi
done
if [ "$crit_info" != "" ]; then
echo -e $crit_info | notification_email
fi
#磁盘监控脚本非常实用,设置告警阈值,超过阈值就发送邮件进行告警。sendEmail是个开源工具
#http://caspian.dotconf.net/menu/Software/SendEmail/下载最新版本
#互联网设置QQ邮箱:CentOS系统设置QQ邮箱
#第一步:网页打开QQ邮箱,设置》账户》IMAP/SMTP服务开启
#第二步:发送短信,获取授权码
#第三步:确认CentOS打开postfix服务命令systemctl status postfix,结果出现绿色字体的active(running)
systemctl status postfix
#第四步:确认是否安装mailx,命令which mailx
which mailx
#第五步:使用SMTP非加密端口发送邮件
cat >> /etc/mail.rc <<EOF
#显示的发件人,必须和用户认证邮箱一致
set from=*****@qq.com
set smtp=smtp.qq.com
#smtp用户认证邮箱
set smtp-auth-user=*****@qq.com
#授权码
set smtp-auth-password=xxxxxxxxxxx
#默认是login,也可改为CRAM-MD5或PLAIN方式
set smtp-auth=login
EOF
#第六步:使用SSL加密方式,需要QQ邮箱的SSL证书,手动获取命令如下
#1、创建存放证书的目录
mkdir -p /root/.certs/
#2、获取QQ邮箱的SSL证书
echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICAT-/,/-END CERTIFICAT-/p' > ~/.certs/qq.crt
#3、添加第一个证书到证书数据库中
certutil -A -n "GeoTrust SSL CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crt
#4、添加第二个证书到证书数据库中
certutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crt
#5、列出指定目录下的所有证书
certutil -L -d /root/.certs
#结果如:Certicate Nickname
# Trust Attribute
# SSL,S/MIME,JAR/XPI
# GeoTrust SSL CA
#6、如果显示Error in certificate:Peer‘s certificate issuer is not recognized,运行如下命令
cd /root/.certs ll certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ./ -i qq.crt
#第七步:测试命令
echo 'This is a test.--From Postfix' | mail -s "Test Postfix" *****@qq.com
#!/usr/bin/sh
#批量自动创建用户脚本
#默认会创建pws0~pws9这10个系统用户,用户名和密码保存在list_user文件中
DATE=`date "+%F_%T"`
USER_FILE=list_user
if [[ -s ${USER_FILE} ]]
then
mv ${USER_FILE} ${USER_FILE}-${DATE}.bak
fi
echo -e "User\t Password" >> ${USER_FILE}
for USER in pws{0..9}
do
if ! id ${USER} &>/dev/null
then
PASS=$(echo ${RANDOM} | md5sum | cut -c 1-8)
useradd ${USER}
echo -e ${PASS} | passwd --stdin ${USER} &>/dev/null
echo -e "${USER}\t ${PASS}">>${USER_FILE}
echo -e "${USER} USER CRERATE SUCCESSFUL"
fi
done
#!/bin/bash
#根据PID过滤进程所有信息
read -p "请输入要查询的PID:" p
n=`ps aux | awk '$2~/^'$p'$/{print $11}' | wc -l`
if [ $n -eq 0 ]; then
echo "该PID不存在"
exit
fi
echo "-------------------"
echo "进程PID: $p"
echo "进程命令:`ps aux | awk '$2~/^'$p'$/{print $11}'`"
echo "进程所属用户:`ps aux | awk '$2~/^'$p'$/{print $1}'`"
echo "CPU占用率:`ps aux | awk '$2~/^'$p'$/{print $3}'`"
echo "内存占用率:`ps aux | awk '$2~/^'$p'$/{print $4}'`"
echo "进程开始运行的时间:`ps aux | awk '$2~/^'$p'$/{print $9}'`"
echo "进程运行的持续时间:`ps aux | awk '$2~/^'$p'$/{print $10}'`"
echo "进程状态:`ps aux | awk '$2~/^'$p'$/{print $8}'`"
echo "进程虚拟内存:`ps aux | awk '$2~/^'$p'$/{print $5}'`"
echo "进程共享内存`ps aux | awk '$2~/^'$p'$/{print $6}'`"
echo "-------------------"
#!/bin/bash
#根据进程名查看进程状态
read -p "输入进程名:" NAME
#统计进程总数
N=`ps aux | grep $NAME | grep -v grep | wc -l`
if [ $N -le 0 ]; then
echo "该进程名没有运行!"
fi
i=1
while [ $N -gt 0 ]
do
echo "进程PID:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $2}'`"
echo "进程命令:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $11}'`"
echo "进程所属用户:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $1}'`"
echo "CPU占用率:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $3}'`"
echo "内存占用率:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $4}'`"
echo "进程开始运行的时刻:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $9}'`"
echo "进程运行的时间:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $11}'`"
echo "进程状态:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $8}'`"
echo "进程虚拟内存:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $5}'`"
echo "进程共享内存:`ps aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}' | awk '{print $6}'`"
echo "************************************"
let N-- i++
done
#!/bin/bash
#根据提供的用户查询该用户的所有信息
read -p "请输入你要查询的用户:" A
echo "---------------------------------"
n=`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | wc -l`
if [ $n -eq 0 ]; then
echo "该用户不存在"
echo "---------------------------------"
else
echo "用户名:$A"
echo "用户的UID:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | awk -F: '{print $3}'`"
echo "用户的组为:`id $A | awk {'print $3'}`"
echo "用户的GID为:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | awk -F: '{print $4}'`"
echo "用户的家目录:`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | awk -F: '{print $6}'`"
Login=`cat /etc/passwd | awk -F: '$1~/^'$A'$/{print}' | awk -F: '{print $7}'`
if [ $Login == "/bin/bash" ]; then
echo "此用户有登陆系统的权限"
echo "---------------------------------"
elif [ $Login == "/sbin/nologin" ]; then
echo "此用户没有登陆系统的权限"
echo "---------------------------------"
fi
fi
#加固系统是运维必备工作,脚本对系统用户和账号进行安全加固
#! /bin/bash
read -p "设置密码最长过期天数: " A
read -p "设置密码修改最短天数: " B
read -p "设置密码最短长度: " C
read -p "设置密码过期前警告天数: " D
sed -i '/^PASS_MAX_DAYS/c\PASS_MAX_DAYS '$A'' /etc/login.defs
sed -i '/^PASS_MIN_DAYS/c\PASS_MIN_DAYS '$B'' /etc/login.defs
sed -i '/^PASS_MIN_LEN/c\PASS_MIN_LEN '$C'' /etc/login.defs
sed -i '/^PASS_WARN_AGE/c\PASS_WARN_AGE '$D'' /etc/login.defs
echo "对密码已进行加固,新密码必须同时包含数字、小写字母、大写字母,且新密码不得和旧密码相同"
sed -i '/pam_pwquality.so/c\password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= difok=1 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1' /etc/pam.d/system-auth
echo "对密码已进行安全加固,如果输入错误密码超过3次,就锁定账户"
n=`cat /etc/pam.d/sshd | grep "auth required pam_tally2.so" | wc -l`
if [ $n -eq 0 ]; then
sed -i '/%PAM-1.0/a\auth required pam_tally2.so deny3 unlock_time=150 even_deny_root root_unlock_time300' /etc/pam.d/sshd
fi
echo "已设置禁止root用户远程登陆"
sed -i '/PermitRootLogin/c\PermitRootLogin no' /etc/ssh/sshd_config
read -p "设置历史命令保存条数:" E
read -p "设置账户自动注销时间:" F
sed -i '/^HISTSIZE/c\HISTSIZE='$E'' /etc/profile
sed -i '/^HISTSIZE/a\TMOUT='$F'' /etc/profile
echo "只允许wheel组的用户可以用su命令切换到root用户"
sed -i 'pam_wheel.so use_uid/c\auth required pam_wheel.so use_uid ' /etc/pam.d/su
n=`cat /etc/login.defs | grep SU_WHEEL_ONLY | wc -l`
if [ $n -eq 0 ]; then
echo SU_WHEEL_ONLY yes >> /etc/login.defs
fi
echo "即将对系统中的用户进行检查"
echo "系统中有登录权限的用户有:"
awk -F: '($7=="/bin/bash"){print $1}' /etc/passwd
echo "-----------------------------------------------"
echo "系统中UID=0的用户有:"
awk -F: '($3=="0"){print $1}' /etc/passwd
echo "-----------------------------------------------"
N=`awk -F: '($2==""){print $1}' /etc/shadow | wc -l`
echo "系统中无密码的用户有:$N"
if [ $N -eq 0 ]; then
echo "恭喜,系统中没有空密码用户"
echo "-----------------------------------------------"
else
i=1
while [ $N -gt 0 ]
do
None=`awk -F: '($2==""){print $1}' /etc/shadow | awk 'NR=='$i'{print}'`
echo "-----------------------------------------------"
echo $None
echo "必须为无密码用户设置密码"
passwd $None
let N--
done
M=`awk -F: '($2==""){print $1}' /etc/shadow | wc -l`
if [ $M -eq 0 ]; then
echo "恭喜,系统中已经没有空密码用户"
else
echo "系统中还存在空密码用户:$M"
fi
fi
echo "即将对系统中重要文件进行锁定,锁定后将无法添加、删除用户和组"
read -p "警告:此脚本运行后将无法添加删除用户和组,确定输入Y,取消输入N;Y/N:" i
case $i in
[Y,y])
chattr +i /etc/passwd
chattr +i /etc/shadow
chattr +i /etc/group
chattr +i /etc/gshadow
echo "锁定成功"
;;
[N,n])
chattr +i /etc/passwd
chattr +i /etc/shadow
chattr +i /etc/group
chattr +i /etc/gshadow
echo "取消锁定成功"
;;
*)
echo "请输入Y/y or N/n"
esac
#! /bin/bash
#host是需要检测的MySQL主机的IP地址,user为MySQL账户名,passwd为密码
host=172.16.213.30
user=root
passwd=xxxxxxxxx
mysqladmin -h '$host' -u '$user' -p '$passwd' ping &>/dev/null
if [ $? -eq 0 ]
then
echo "MySQL is UP"
else
echo "MySQL is down"
fi
#脚本借助mysqladmin命令
#MySQL主从复制架构在企业应用广泛,主从状态的监控也是运维的一部分
#! /bin/bash
USER=ixdba
PASSWD=xxxxxxxx
IO_SQL_STATUS=$(mysql -u $USER -p $PASSWD -e 'show slave status\G' | awk -F: '/Slave_.*_Running/{gsub(": ",":");print $0}')
for i in $IO_SQL_STATUS; do
THREAD_STATUS_NAME=${i%:*}
THREAD_STATUS=${i#*:}
if [ "THREAD_STATUS" != "Yes" ]; then
echo "Error:MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!"
fi
done
#登陆MySQL,查询主从复制的两个状态值Slave_SQL_Running和Slave_IO_Running,两个值都是Yes则认为正常;
#USER和PASSWD是自己环境的数据库用户名和密码
#! /bin/bash
user=root
passwd=xxxxxxxx
dbname=mysql
date=$(date +%Y%m%d)
#测试备份目录是否存在,不存在则自动创建该目录
[ ! -d /mysqlbackup ] && mkdir /mysqlbackup
#使用mysqldump命令备份数据库
mysqldump -u "$user" -p "$passwd" "$dbname" > /mysqlbackup/"$dbname"-${date}.sql
#使用mysqldump命令方便,大量数据备份时力不从心
#! /bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=172.16.213.220
DB=ixdba
USER=ixdba
PASS=xxxxxxxx
MAIL="[email protected] [email protected]"
BACKUP_DIR=/data/db_backup
SQL_FILE=${DB}_full_$DATE.sql
BAK_FILE=${DB}_full_$DATE.zip
cd $BACKUP_DIR
if mysqldump -h $HOST -u $user -p $PASS --single-transaction --routines --triggers -B $DB > $SQL_FILE; then
zip $BAK_FILE $SQL_FILE && rm -f $SQL_FILE
if [ ! -s $BAK_FILE ]; then
echo "$DATE 内容" | mail -s "主题" $MAIL
fi
else
echo "$DATE 内容" | mail -s "主题" $MAIL
fi
find $BACKUP_DIR -name '*.zip' -ctime +7 -exec rm {} \;
#脚本通过mysqldump进行数据库备份,对备份的SQL文件进行压缩和校验,并删除一周之前的备份
#! /bin/bash
#一个简单的一键自动化安装脚本
function IXDBA(){
cat <<EOF
-----------------------------------------------------------------------------------------
一键安装Nginx脚本
-----------------------------------------------------------------------------------------
EOF
}
IXDBA
if [ ! -d /usr/local/src ]
then
mkdir /usr/local/src
fi
LOG_DIR=/usr/localsrc
function NGINC_INSTALL(){
yum install -y gcc gcc-c++ pcre-devel zlib-devel openssl-devel &>/dev/null
if [ $? -eq 0 ]
then
cd $LOG_DIR
&& wget http://nginx.org/download/nginx-1.14.2.tar.gz &>/dev/null
&& useradd -M -s /sbin/nologinnginx
&& tar -zxf nginx-1.14.2.tar.gz
&& cd nginx-1.14.2/
&& ./configure --prefix=/usr/local/nginx
--with-http_dav_module
--with-http_stub_status_module
--with-http_additon_module
--with-http_sub_module
--with-http_flv_module
--with-http_mp4_module
--with-pcre
--with-http_ssl_module
--with-http_gzip_static_module
--user=nginx &>/dev/null
&& make &>/dev/null
&& make install &>/dev/null
fi
if [ -e /usr/local/nginx/sbin/nginx ]; then
/usr/local/nginx/sbin/nginx && echo "Nginx安装并启动成功!!!"
fi
}
echo "开始安装Nginx 请稍等..." && NGINX_INSTALL
#可以仿照nginx,编写一键安装MySQL、PHP、Zabbix
#!/bin/bash
read -p "please input a IPv4 netphase: " n
a=1
while :
do
a=$(($a+1))
if test $a -gt 255
then break
else
echo $(ping -c 1 $n.$a | grep "ttl" | awk '{print $4}' | sed 's/://g')
ip=$(ping -c 1 $n.$a | grep "ttl" | awk '{print $4}' | sed 's/://g')
echo $ip >> ip.txt
fi
sed -i '/^$/d' ip.txt
done
cat ip.txt
#!/bin/bash
#监控网站页面是否正常访问
source /etc/profile
read -p "input a website you want to know whether ok or not ok:" website
A="Web is Ok"
ip=`/sbin/ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v 192 | grep -v inet6 | awk '{print $2}' | tr -d "addr:"`
ttl=`curl -I -s ${website} | head -1 | cut -d " " -f2`
Process=`ps -ef | grep java | grep -E "tomcat" | awk -F " " '{print $2}'`
if [ ${ttl} = "200" ]
then
echo "${A}" >> website-log.`date +%F`.log
else
echo ${ttl} ${Process} >> website-log.`date +%F`.log
fi
1,用户与角色分类,linux用户是根据角色定义
的,具体分三种角色
默认是root用户
登陆系统的权限,如WWW用户,FTP用户 等
.系统默认的bin,adm,nobody用户等
.2,用户和组以及关系
.使用系统资源必须向系统管理员申请一个账户,通过账户进入系统(账户和用户是一个概念).不同属性的用户:一方面合理地
利用和控制系统资源;另一方面帮助用户组织文件,提供对用户文件的
安全性保护`.用户组是具有相同特征用户的逻辑集合,
有时需要多个用户具有相同权限,例如10个用户需要查看修改某一文件的权限:一种方法授权给10个用户;另一种方法,建立一个组,让这个组具有权限,再将需要权限的用户放入这个组.用户进行管理及控制访问权限的一种手段
.用户和用户组的关系:一对一,一对多,多对一,多对多.
3,用户和组相关的配置文件
(1)/etc/passwd文件
系统用户配置文件,是用户管理中最重要的文件.
记录Linux系统中每个用户的基本属性,并且对所有用户可读
,每一行记录对应一个用户,每行记录被冒号分隔用户名:口令:用户标识号:组标识号:注释性解释:主目录:默认shell(共7项数据)
UID取值范围0-65535,0是超级用户root的标识号,1-99系统保留,普通用户标识号从100开始,Linux系统中,普通用户默认从500开始.
UID是Linux系统下确认用户权限的标志.shell是用户和系统内核之间的接口
.用户的任何操作都是通过shell传递给系统内核.管理员可以根据用户习惯给不同用户设置不同shell.(2)/etc/shadow文件,root有读权限:
用户名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:保留字段
*,!,x
等字符,则用户不能登陆系统不活动时间
表示用户口令作废多少天后,系统会完全禁用此用户失效时间
是账号的生存期,超过这个期限账号失效,用户无法登陆系统,字段值为空永久有效(3),/etc/group文件
组名(字母和数字构成):口令(密码默认设置在/etc/gshadow):组标识符(GID):组内用户列表(用户之间用逗号隔开)
(4),/etc/login.defs
MAIL_DIR /var/spool/mail
PASS_MAX_DAYS 9999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
#口令到期前多少天警告用户
PASS_WARN_AGE 7
UID_MIN 500
UID_MAX 60000
GID_MIN 500
GID_MAX 60000
GREATE_HOME yes
(5),/etc/default/useradd
useradd命令不加任何参数创建一个用户,默认主目录位于/home,默认shell是/bin/bash
GROUP=100
HOME=/home
#不启用账号过期禁用
INACTIVE=-1
#不设置账号过期日期
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no
#改变此文件通过:1,文件编辑器;2,useradd命令.
useradd -D [-g group] [-b base] [-s shell] [-f inactive] [-e expire]
#显示当前/etc/default/useradd当前设置
useradd -D
(6),/etc/skel
.bash.profile,bashrc,bash_logout
等文件1,groupadd命令
#-g 新建用户组的GID,唯一
#-o 一般与-g选项同时使用,新用户组的GID可与系统已用用户组GID相同
groupadd [-g -o] gid group
2,newgrp命令
#newgrp主要用于在多个用户组之间切换
useradd -g group -G group0 group1 user
su - user
newgrp [usergroup]
3,groupdel
#删除用户组
groupdel [usergroup]
#先删除该组用户才能删除用户组
1,useradd建立用户的过程
2,useradd的使用语法
useradd [-u uid [-o]] [-g group] [-G group,...] [-d home] [-s shell] [-c comment] [-f inactive] [-e expire] name
#-f inacitve指定账号过期多长时间后永久停用,当值为0时账号立刻被停用;当值为-1时则关闭此功能(预设值-1)
#-e expire指定用户的账号过期时间,日期的指定格式为MM/DD/YY
3,usermod的使用语法
#usermod修改用户的账户的属性信息
usermod [-u uid [-o]] [-g group] [-G group0,group1,,,] [-d 主目录 [-m]] [-s shell] [-c 注释] [-l 新名称] [-f 失效日期] [-e 过期日期] [-L|-U] Name
#-L锁定用户密码,使密码无效。-U解除密码锁定
4,userdel语法使用
#userdel用来删除一个用户
userdel -r user
#-r 不仅删除用户,还删除用户的主目录以及目录下的所有文件
5,应用举例
#添加一个用户mylinux
useradd -g root -G linux -d /opt/mylinux
useradd -u 686 -s /bin/csh -G linux,fanlinux -c "this is a test" test_user
groupadd test_group
usermod -g test_group -G fanlinux,root -s /bin/bash test_user
#如何锁定密码,解锁用户密码
passwd test_user
su - test_user
#root切换到普通用户不需要密码,普通用户之间切换需要密码
usermod -L test_user
whoami
su - test_user
usermod -U test_user
su - test_user
-#表示普通文件
d#表示目录
c#字符设备文件
b#块设备文件
s#套接字文件
p#管道
l#符号链接文件
.#代表当前目录
..#代表上级目录
ls
ls -al #显示文件和目录的权限信息
#文档类型与权限,硬链接数,文档所属的用户和用户组,文档的大小,文档的最后修改时间,文档名称
#文档类型与权限:文档类型,文档拥有者的权限(user),文档所属用户组的权限(group),其他用户的权限(others)
chmod #文档的操作权限的制定和更改
#连接数,硬链接的概念,多少个文件指向同一个索引节点
ln install.log install.log1
ln install.log install.log2
#为install.log做了两个硬链接,install.log的连接数变为3
chown #修改文档的用户属性
#文档的大小默认以Bytes为单位,对于目录通常只显示文件系统默认block的大小
ls -sh #组合人性化的显示文档的大小
#文档名称,以"."开头的是隐藏文档。
chown [-R] 用户名称 文件或目录
chown [-R] 用户名称:用户组织名称 文件或目录
#-R递归式的权限修改,进行操作前确保用户和用户组存在于系统
1,字符设定使用语法
chmod [who] [+|-|=] [mode] 文件名
#who表示操作对象,可以是下面字母中的一个或者他们的任意组合:
#u表示用户(user),即文件或目录的所有者;g表示用户组(group),即文件或目录所属的用户组;o表示其他(other)用户;a表示所有用户,它是系统的默认值
#操作符定义如下:
#+表示添加某个权限;-表示取消某个权限;=表示赋予给定的权限,同时取消文档以前的所有权限
#mode表示可以执行的权限,r,w,x(可读,可写,可执行),以及他们的组合
#文件名可以是以空格分开的文件列表,支持通配符wildchar
chmod u=rwx,g+r,o+r install.log
chmod u-x,g-r,o-r install.log
2,数字设定法
# 0表示没有任何权限,1表示可执行权限,2表示可写权限,4表示可读权限
chmod 755 mysql.sh
1,#fdisk参数含义介绍,fdisk的使用格式:
#fdisk是linux系统下一款功能强大的磁盘分区管理工具。观察磁盘使用情况,对磁盘进行分割,相似工具cfdisk,parted等。
fdisk [-l] [-b SSZ] [-u] device
fdisk -l /dev/sda #-l查看制定设备的分区状况,选项后不加任何设备,则查看系统所有设备的分区状况
#-b SSZ 将指定的分区大小输出到标准输出上,单位为区块。
#-u,一般与-l选项配合使用,显示结果将用扇区数目取代柱面数目,用来表示每个分区的起始地址。
#device要显示或操作的设备名称。
#fdisk分为两个部分:查询部分和交互操作部分,通过fdisk进入命令交互操作界面,输入m显示交互操作下所有可使用的命令。
a #设定硬盘启动区
b #编辑一个BSD类型分区
c #编辑一个DOS兼容分区
d #删除一个分区
l #查看制定分区的分区表信息
m #显示fdisk每个交互命令的详细含义
n #增加一个新的分区
o #创建一个DOS分区
p #显示分区信息
q #退出交互操作,不保存操作的内容
s #创建一个空的Sun分区表
t #改变分区类型
v #校验硬盘分区表
w #写分区表信息到硬盘,保存操作并退出
x #执行高级操作模式
d,l,m,n,p,q,w #常用选项。
2,fdisk实例讲解
#创建磁盘分区
#linux系统新增了一块硬盘,系统对应的设备名为/dev/sdb,现在通过fdisk对磁盘sdb进行分区划分
fdisk /dev/sdb
n #输入n创建一个新的分区
e #这里的e表示创建一个扩展分区
p #这里的p表示创建一个主分区
1 #主分区的编号从1~4,这里输入1
[Enter]键 #这里制定主分区的起始值,以柱面为单位计数,默认从1开始,直接按[Enter]键即可
+8G #这里指定分区的大小,直接输入需要的分区大小即可,例如,+1024M表示此分区大小1024M,+8G表示此分区大小为8G.
p #这里输入p显示分区情况,从下面可以看到,此分区已经建立起来。
#扩展分区也属于主分区,数字必需在1~4,且未使用。
#根据磁盘分区的划分标准,如果要建立扩展分区,最好将磁盘所有剩余空间都分给扩展分区,“p #这里的p表示创建一个主分区”这里直接按[Enter]键,磁盘剩余空间全部分给扩展分区。
l #这里的l表示创建一个逻辑分区
#修改磁盘分区类型
#linux系统下根据ID值区分不同的磁盘分区类型,fdisk默认创建的主分区和逻辑分区类型为Linux,对应的ID为83
#扩展分区默认为Extended,对应的ID为5.如果想要修改分区类型或者创建一个非默认的分区类型,需要交互参数t来指定。
t #输入t改变磁盘分区的类型
5 #要改变的磁盘分区对应的分区号,这里输入的5代表/dev/sdb5
L #通过L可以查看分区类型对应的ID值
7 #从上面的输出可知,7对应的分区类型为HPFS/NTFS
#分区的删除
#删除分区的参数是d,然后指定要删除的分区号,此分区就被删除了
fdisk /dev/sdb
d #这里输入删除分区的指令
6 #这里输入6表示要删除的分区是/dev/sdb6
#保存分区设置
#所有分区操作完成后,输入fdisk交互指令w即可保存分区设置退出;不保存分区设置按q退出。
#磁盘分区划分完毕,还是不能使用,还需将分区格式化为需要的文件系统类型。linux系统下默认支持EXT2,EXT3,EXT4,VFAT等文件系统。
mkfs.ext4 /dev/sdb1 #通过mkfs.ext4命令格式化分区/dev/sdb1
#分区格式化完毕,最后一步是挂载(mount)此设备。
mkdir /data
mount /dev/sdb1 /data
df | grep /data
1,fdisk只能对小于2T的磁盘进行划分分区,磁盘分区工具parted用于完成大于2T的磁盘分区工作
parted由GNU组织开发,功能更丰富:创建分区,调整分区大小,移动和复制分区,删除分区等.
parted分为两种模式:命令行模式(适合编程应用);交互模式简单方便.
2,parted使用方法
yum -y install parted
#parted进入交互模式
parted
#获取帮助信息
help
#创建分区,也就是设置使用msdos还是使用gpt格式.例如,模块mklabel gpt 标识设定分区表为gpt格式
mklabel gpt
#创建新分区命令.使用格式mkpart PART-TYPE [FS-TYPE] [START] [END]
#其中PART-TYPE表示分区类型,主要有主分区primary,扩展分区extended,逻辑分区logical,扩展分区和逻辑分区只针对MS-DOS分区表
#FS-TYPE表示文件系统类型,主要有:FAT32,NTFS,EXT,EXT3等,可不填写.
#START分区起始位置
#END分区的结束位置
mkpart primary EXT3 0gb 10gb
#输出分区信息,可简写为p,该功能由三个选项,free希纳是该盘的所有信息,并显示磁盘的剩余空间;
#number显示指定的分区的信息;all或list显示所有磁盘信息
print free
#删除分区.命令格式:rm number.例如:rm 3就是将磁盘分区3删除
rm 3
#选择设备,当输入parted命令后直接按[Enter]键进入交互模式时,默认设置是系统的第一块磁盘,如果系统有多块磁盘,需要用select命令选择要操作的硬盘
select /dev/sdb
#parted创建文件系统的功能有但较弱,一般是parted进行磁盘分区后,退出parted交互模式,用其他命令创建文件系统
mkfs.ext4 /dev/sdb1
3,parted应用实例
parted
select /dev/sdb
p
mklabel gpt
mkpart primary 0gb 10gb
mkpart primary 10gb 15gb
p freee
mkpart primary 15gb 21.5gb
p
rm 3
mk.xfs /dev/sdb1
mkdir /data
mount /dev/sdb1 /data
df | grep /data
Linux系统中DOS文件系统类型MS-DOS;
Windows系统中FAT系列(FAT16和FAT32)和NTFS文件系统
光盘文件系统ISO-9660
单一文件系统EXT2和日志文件系统EXT3,EXT4,XFS
集群文件系统GFS(Red Hat Global File System)
分布式文件系统HDFS
虚拟文件系统/proc
网络文件系统NFS等
1,读操作频繁同时小文件众多的应用(例如网站应用和邮件系统),选择EXT4文件系统.
EXT3目录是线型,目录众多性能降低.
EXT4延迟分配,多块分配和盘区功能,非常适合大量小文件的操作,更高效
性能和安全方面考虑,XFS文件系统是较好选择
2,写操作频繁的应用(大数据文件操作,应用本身需要大量日志写操作)
XFS文件系统内是最佳的选择(效率更高,CPU利用率最好)
XFS,EXT4,EXT3块写入性能差不多,效率由高到低XFS,EXT4,EXT3
3,对性能和安全性要求不高的应用(Linux系统下/tmp采用EXT2文件系统)
EXT3和EXT2文件系统是比较好的选择,EXT2没有日志记录功能,节省很多磁盘性能.
以centos为例
1,安装NFS
#检查系统是否安装NFS相关服务
rpm -qa | grep rpcbind
rpm -qa | grep nfs
2,NFS Server端的设定
#NFS主要配置文件/etc/exports,格式如下:共享资源路径 [主机地址] [选项]
cat /etc/exports
/webdata *(sync,rw,all_squash)
/tmp *(rw,no_root_squash)
/home/share 192.168.1.*(rw,root_squash) *(ro)
/opt/data 192.168.1.18(rw)
/user/local/doc *.ixdba.net(rw,anonuid=686,anongid=686)
#启动/停止NFS服务
#start启动服务,stop停止服务,restart重启服务,enable服务开机自启动
systemctl start/stop/restart/enable nfs
systemctl start/stop/restart/enable rpcbind
#通过exportfs命令临时增加一个共享策略
#临时策略,如果NFS服务重启,或者通过r参数重新mount后,该策略会消失,类似ifconfig命令
exportfs 192.168.60.108:/home/test_user
exportfs
3,NFS客户端的设定
yum -y install nfs-utils
systemctl start rpcbind
systemctl enable rpcbind
#如果NFS Server开启防火墙,最好关闭防火墙保证客户端正常连接
systemctl stop firewalld
systemctl diable firewalld
#Hostname:用来指定NFS Server的地址,可以是IP地址或主机名
#/directory: 表示NFS Server共享出来的目录资源
#mountpoint: 表示客户端指定的挂载点.通常是一个空目录
mount -t nfs Hostname(orIP):/diretory /mountpoint
mount -t nfs 192.168.60.133:/mydata /data/nfs
#编辑/etc/fstab文件
192.168.60.133:/mydata /data/nfs nfs defaults 0 0
umount /mountpoint
umount /data/nfs
4,NFS Server的安全设定
#Linux的NFSD的COPY数目,通过/etc/sysconfig/nfs启动文件中的RPCNFSDCOUNT参数进行设置
#默认是8个NFSD
systemctl restart nfs-config
systemctl restart nfs
*进程是在自身的虚拟地址空间运行的一个独立程序.
1,进程的分类
2,父进程与子进程
1,利用ps命令监控系统进程
#输出关于apache的信息
ps -ef | head -n 1;ps -ef | grep httpd
#查看父子进程的关系
#%CPU,%MEM,VSZ进程虚拟内存大小,RSS进程实际内存(驻留集)大小(单位是项),STAT表示进程的状态,START表示进程启动时间
#R正在运行中的进程,S表示处于休眠状态的进程,Z表示僵死进程,<表示优先级高的进程,N表示优先级较低的进程,s表示父进程,+表示位于后台的进程
ps -auxf | head -n 1;ps -auxf | grep httpd
2,利用top监控系统进程
3,利用lsof监控系统进程和程序
#lsof filename,显示使用filename文件的进程,COMMAND对应的字段表示使用文件的进程.
lsof /var/log/messages
#显示nfs进程现在打开的文件
#FD列表示文件描述符,TYPE列显示文件的类型,SIZE列显示文件的大小,NODE列显示本地文件的node码,NAME列显示文件的全路径或挂载点
lsof -c nfs
#显示指定进程组打开的文件情况
#PGID列表示进程组的ID号,例如sendmail程序当前打开的所有文件,设备,库或套接字等
lsof -g gid
#PID是进程号,通过进程号显示程序打开的所有文件和相关进程,例如想知道init进程打开那些文件
lsof -p PID
#通过监听指定的协议,端口,主机等信息,显示符合条件的进程信息.语法:
#lsof -i [46] [protocol] [@hostname] [:service|port]
#4代表IPv4,6代表IPv6,protocol传输协议可以是TCP或UDP,hostname主机名或者IP地址,
service进程的服务名例如NFS,SSH,FTP等,port系统中服务对应的端口号例如HTTP服务默认对应80端口,ssh服务默认端口22等.
4,利用pgrep查询进程ID
#检查程序在系统中活动的进程,输出进程属性匹配命令行上指定条件的进程ID,
#每个进程ID以十进制表示,通过分隔字符串和下一个ID分开.
#判断程序是否正在运行,迅速直到进程PID的需求
pgrep 参数选项 command
#-l列出程序名和进程ID值,-o用来显示进程起始的ID值,-n用来显示进程终止的ID值,
#-f可以匹配command中的关键字,即为字符串匹配,-G可以匹配指定组启动的进程对应的ID值
pgrep -lo httpd
pgrep -ln httpd
pgrep -f sshd
pgrep -G www_data
#系统任务调度,系统周期性所要执行的工作,如写缓存数据到磁盘,日志清理等
#在/etc/crontab文件,此文件就是系统任务调度的配置文件
cat /etc/crontab
#前4行用来配置crond任务运行的环境变量:系统使用哪个shell,系统执行命令的路径,crond的任务执行信息将通过电子邮件发送给root用户,执行命令或脚本时使用的主目录
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin/:usr/bin
MAILTO=root
HOME=/
#run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
#用户调度任务,用户定期要执行的工作,如用户数据备份,定时邮件提醒等.
#用户可以使用crontab工具定制自己的计划任务
#所有用户定义的crontab文件都被保存在/var/spool/cron目录中,其文件名与用户名一致
2,crontab工具的使用
(1)crontab的使用格式
#crontab常用的使用格式由如下两种
#-u用来设定某个用户的crontab服务,此参数一般由root用户来运行
#file是命名文件的名字,表示将file作为crontab的任务列表文件并载入crontab,如果未指定将接受标准输入
#-e编辑某个用户的crontab文件内容,如果不指定用户,则表示当前用户的crontab文件
#-l显示用户的crontab文件内容,如果不指定用户,则显示当前用户的crontab文件内容
#-r从/var/spool/cron目录中删除某个用户的crontab文件,不指定用户,则删除当前用户的crontab文件
#-i在删除用户的crontab文件时给确认提示
crontab [-u user] [file]
crontab [-u user] [-e|-l|-r|-i]
(2)crontab文件的含义
#用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,共六个字段,前五个字段是时间设定段,第六段是要执行的命令段
#'*'代表所有可能值,','逗号隔开的值指定一个列表范围,'-'整数之间的中杠表示一个整数范围,'/'正斜杠指定时间的间隔频率
minute0-59 hour0-23 day1-31 month1-12 week0-7sunday command系统命令&脚本文件
0 */3 * * * /user/local/apache2/apachectl restart
30 3 * * 6 /webdata/bin/backup.sh
0 0 1,20 * * fsck /dev/sdb8
10 5 */5 * * echo " " >/user/local/apache2/log/access_log
3,使用crontab工具的注意事项
(1)注意环境变量问题
(2)注意清理系统用户的邮件日志
# >/dev/null 2>&1 先将标准输出重定向到/dev/null,然后将错误重定向到标准输出,标准输出和错误输出都输出到/dev/null
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
(3)系统级任务调度和用户级任务调度
#root用户的任务调度操作通过crontab -u root -e来实现
#或者将调度任务直接写入/etc/crontab文件
#定义一个定时重启系统的任务,必须放到/etc/crontab文件
crontab -u root -e
1,用kill终止一个进程
#关闭某些服务,关闭处于僵死状态的进程,Linux关闭进程用kill命令.
#首先向操作系统内核发送一个终止信号和终止进程的PID,系统内核根据发送的终止信号类型对进程进行相应的终止操作
kill [信号类型] 进程PID
#查看所有信号类型
kill -l
#强制结束进程
kill -9
#结束进程,非强制性.和[Ctrl]+[C]
kill -2
#正常结束进程,kill的默认选项,kill不加任何信号类型时默认类型就是15
kill -15
kill
#强制关闭一个Apache子父进程,Apache子进程没有因为父进程关闭而自动关闭
#子进程存在,子进程的PPID由原来的5078变成1,这是正常关闭和强制关闭的区别
kill -9 5078
#正常关闭进程,父进程终止时,会同时调用资源关闭子进程,释放内存
#强制关闭进程操作中,忽略进程之间的依赖关系,父进程直接关闭,不去理会子进程
#子进程成了孤儿进程,为让孤儿进程的资源得以释放,系统默认将init进程作为孤儿进程的父进程
#只需要再次执行kill命令关闭相应的子进程即可
2,用killall终止一个进程
#kill的使用语法
#信号类型,与kill中信号类型含义一致
#进程名称,进程对应的名称,例如java,httpd,mysqld,sshd,sendmail等
killall [信号类型] 进程名称
killall httpd