If示例
根据命令的退出状态来执行命令
if ping -c1 -W2 station1 &> /dev/null; then ping一次等待2秒
echo ‘Station1 is UP’
elif grep “station1” ~/maintenance.txt &> /dev/null 主机是否维护
then
echo ‘Station1 is undergoing maintenance‘ 机器down机
else echo ‘Station1 is unexpectedly DOWN!’ exit 1
fi
循环
循环执行
将某代码段重复运行多次
重复运行多少次
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
for, while, until
for循环
for 变量名 in 列表;do 列如:for name in wang mage li lele ;do
循环体
done
执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直
到列表中的元素耗尽,循环结束
for循环
列表生成方式:
(1) 直接给出列表
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用glob,如:*.sh
(5) 变量引用;
$@, $* $@ 独立的字符串,$*整体的字符串
[root@CENTOS7 ~]#for num in 1 2 3 4 5 6 ; do echo num=$num ;done for循环基本用法 手动输入列表
num=1
num=2
num=3
num=4
num=5
num=6
[root@CENTOS7 ~]#echo {10..2..3}
10 7 4
[root@CENTOS7 ~]#for num in {1..10..2} ;do echo num=$num ;done 大括号形成列表
num=1
num=3
num=5
num=7
num=9
[root@CENTOS7 ~]#seq 1 3 10
1
4
7
10
[root@CENTOS7 ~]#for num in `seq 1 3 10` ;do echo sum=$num ;done 命令形成列表
sum=1
sum=4
sum=7
sum=10
[root@CENTOS7 ~]#for file in `ls /boot`;do echo filename=$file;done
filename=config-3.10.0-693.el7.x86_64
filename=efi
filename=grub
filename=grub2
filename=initramfs-0-rescue-d9b2c489cdf948f8b487e98005c15e1c.img
filename=initramfs-3.10.0-693.el7.x86_64.img
filename=initrd-plymouth.img
filename=symvers-3.10.0-693.el7.x86_64.gz
filename=System.map-3.10.0-693.el7.x86_64
filename=vmlinuz-0-rescue-d9b2c489cdf948f8b487e98005c15e1c
filename=vmlinuz-3.10.0-693.el7.x86_64
[root@CENTOS7 ~]#for num in /data/*.sh ;do echo $num ; done 通配符生成列表
/data/arg.sh
/data/f1.sh
/data/f2.sh
/data/f3.sh
/data/install.sh
/data/link.sh
/data/sumuid.sh
/data/username.sh
[root@CENTOS7 ~]#for num in “/data/*.sh” ;do echo $num ; done 加上”” 当成一个字符串来显示
/data/arg.sh /data/f1.sh /data/f2.sh /data/f3.sh /data/install.sh /data/link.sh /data/sumuid.sh /data/username.sh
1一直加到100
[root@CENTOS7 ~]#vim sum.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: sum.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..100} ; do
let sum=sum+i
done
echo $sum
[root@CENTOS7 ~]#./sum.sh
5050
1递进3加到100
[root@CENTOS7 ~]#vim sum147.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: sum147.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i sum=0
for i in `seq 1 3 100` ; do
let sum=sum+i
done
echo $sum
unset sum 清除sum的赋值
“sum147.sh” [New] 16L, 420C written
[root@CENTOS7 ~]#chmod +x sum147.sh
[root@CENTOS7 ~]#./sum147.sh
1717
在for循环中使用多行从定向时,需要在结束符处加-
[root@CENTOS7 ~]#vim f11.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: f11.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..10} ;do
cat >> f1 <<-123
aaa
bbb
123
done
root@CENTOS7 ~]#cat f1
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
创建10个用户是user{1..10} 判断用户是否存在,不存在创建,存在就提示用户已经存在,并设置口令是magedu。
[root@CENTOS7 ~]#cat createuser.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: createuser.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for user in `echo user{1..10}`; do
id $user &> /dev/null
if [ $? -eq 0 ] ; then
echo the user is exist
else useradd $user
echo magedu | passwd –stdin $user
echo user creat succeed
fi
done
扫描地址段
[root@CENTOS7 ~]#vim scanaddress.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: scanaddress.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
addr=172.20.0.
for i in {1..255} ;do
if ping -c1 -w1 $addr$i &>/dev/null ; then
echo $addr$i is up
else
echo $addr$i is down
fi
done
运行太慢,加速运行。后台并行运行
[root@CENTOS7 ~]#vim scanaddress.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: scanaddress.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
addr=172.20.0.
for i in {1..255} ;do
{ if ping -c1 -w1 $addr$i &>/dev/null ; then
echo $addr$i is up
else
echo $addr$i is down
fi ; } &
done
wait 后台运行完毕后自动退出 当执行下面计数的命令使不能再后台并行运行
[root@CENTOS7 ~]#vim scanaddress.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: scanaddress.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
addr=172.20.0.
up=0
down=0
for i in {1..255} ;do
if ping -c1 -w1 $addr$i &>/dev/null ; then
echo $addr$i is up &>/dev/null
let up=$up+1
else
echo $addr$i is down &>/dev/null
let down=$down+1
fi
done
echo up=$up
echo down=$down
“scanaddress.sh” 29L, 597C written
[root@CENTOS7 ~]#./scanaddress.sh
up=2
down=253
addr=172.20.0.
up=0
down=0
for i in {1..255} ;do
ping -c1 -w1 $addr$i &>/dev/null && { echo $addr$i is up; let up++; } || { echo $addr$i is down; let down++; }
done
[root@CENTOS7 ~]#vim addr.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-07
#FileName: addr.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
addr=172.20.0.
up=0
down=0
for i in {1..10} ;do
ping -c1 -w1 $addr$i &>/dev/null && { echo $addr$i is up; let up++; } || { echo $addr$i is down; let down++; }
done
echo $up
echo $down
~
~
~
“addr.sh” 20L, 540C written
[root@CENTOS7 ~]#./addr.sh
172.20.0.1 is up
172.20.0.1 is down
172.20.0.2 is down
172.20.0.3 is down
172.20.0.4 is down
172.20.0.5 is down
172.20.0.6 is down
172.20.0.7 is down
172.20.0.8 is down
172.20.0.9 is down
172.20.0.10 is down
1
10
发现up的机器出现问题,因为up++,当up=0时,执行up++,$?=1
[root@CENTOS7 ~]#up=0
[root@CENTOS7 ~]#let up++
[root@CENTOS7 ~]#echo $?
1
[root@CENTOS7 ~]#n=10;echo {1..$n} {}不支持变量写法
{1..10}
[root@CENTOS7 ~]#n=10;seq 1 $n
1
2
3
4
5
6
7
8
9
10
[root@CENTOS7 ~]#n=10;eval echo {1..$n} eval扫描替换变量,然后在执行命令
1 2 3 4 5 6 7 8 9 10
循环嵌套:
for i in {1..10};do 执行100次
for j in {1..10};do
cmd
done
done
打印一个矩形:
[root@CENTOS7 ~]#vim rectangle.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: rectangle.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
high=$1
wide=$2
for i in `seq $high` ; do
for j in `seq $wide` ; do
echo -e “\033[1;32m*\033[0m\c”
done
echo
done
[root@CENTOS7 ~]#./rectangle.sh 5 10
**********
**********
**********
**********
**********
随机颜色的矩形
[root@CENTOS7 ~]#vim rectangle.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: rectangle.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
high=$1
wide=$2
for i in `seq $high` ; do
for j in `seq $wide` ; do
k=$[$RANDOM%7+31]
echo -e “\033[1;${k}m*\033[0m\c”
done
echo
done
[root@CENTOS7 ~]#./rectangle.sh 5 10
**********
**********
**********
**********
**********
99乘法表
[root@CENTOS7 ~]#vim 9*9.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: 9*9.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..9} ; do
for j in `seq 1 $i` ; do
result=$[$i*$j]
echo -e “${j}x${i}=$result\t\c”
done
echo
done
~
~
~
~
~
~
~
~
~
~
~
“9*9.sh” 18L, 457C written
[root@CENTOS7 ~]#./9\*9.sh
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
取8个随机字母
[root@CENTOS7 ~]#openssl rand -base64 20 | tr -dc “[:alpha:]” | head -c8
cxHNcKmG[root@CENTOS7 ~]#
国际象棋棋盘
high=$1
wide=$2
r i in `seq $high` ; do
a=$[$i%2]
for j in `seq $wide` ; do
if [ $a -eq 1 ] ; then
echo -e “\033[1;42m \033[0m\033[1;41m \033[0m\c”
else
echo -e “\033[1;41m \033[0m\033[1;42m \033[0m\c”
fi
done
echo
大的国际象棋盘
for i in {1..16};do
for j in {1..4};do
case $[i%4] in
1|2)
echo -e “\033[1;41m \033[0m\033[1;43m \033[0m\c”
;;
*)
echo -e “\033[1;43m \033[0m\033[1;41m \033[0m\c”
;;
esac
done
echo
done
while循环
while CONDITION; do
循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后
会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为
“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地
被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
[root@CENTOS7 ~]#vim sum100.sh
#!/bin/bash
declare -i sum=0
i=1
while [ $i -le 100 ]; do
let sum=sum+i
let i=i+1
done
echo $sum
[root@CENTOS7 ~]#./sum100.sh
5050
用while实现9*9法则
[root@CENTOS7 ~]#vim while9*9.sh
#!/bin/bash
declare -i i=1
while [ $i -le 9 ]; do
declare -i j=1
while [ $j -le $i ]; do
sum=$[${j}*${i}]
echo -e “${j}x${i}=$sum\t\c”
let j++
done
echo
let i++
done
~
“while9*9.sh” 22L, 509C written
[root@CENTOS7 ~]#./while9*9.sh
1×1=1
1×2=22×2=4
1×3=32×3=63×3=9
1×4=42×4=83×4=124×4=16
1×5=52×5=103×5=154×5=205×5=25
1×6=62×6=123×6=184×6=245×6=306×6=36
1×7=72×7=143×7=214×7=285×7=356×7=427×7=49
1×8=82×8=163×8=244×8=325×8=406×8=487×8=568×8=64
1×9=92×9=183×9=274×9=365×9=456×9=547×9=638×9=729×9=81
每10秒监控一次httpd服务,如果服务停止则启动。
[root@CENTOS7 ~]#systemctl start httpd
[root@CENTOS7 ~]#ss -ntl
LISTEN 0 128 :::80 :::*
[root@CENTOS7 ~]#ps -aux | grep httpd
root 6196 0.5 0.4 226240 5132 ? Ss 13:44 0:00 /usr/sbin/httpd -DFOREGROUND
apache 6207 0.0 0.2 228324 3152 ? S 13:45 0:00 /usr/sbin/httpd -DFOREGROUND
apache 6208 0.0 0.2 228324 3152 ? S 13:45 0:00 /usr/sbin/httpd -DFOREGROUND
apache 6209 0.0 0.2 228324 3152 ? S 13:45 0:00 /usr/sbin/httpd -DFOREGROUND
apache 6210 0.0 0.2 228324 3152 ? S 13:45 0:00 /usr/sbin/httpd -DFOREGROUND
apache 6211 0.0 0.2 228324 3152 ? S 13:45 0:00 /usr/sbin/httpd -DFOREGROUND
root 6244 0.0 0.0 112660 972 pts/0 R+ 13:45 0:00 grep –color=auto httpd
[root@CENTOS7 ~]#vim start.sh
while true ; do
if pgrep httpd &> /dev/null ;then 这里也可以写成 if killall -0 httpd &> /dev/null ;then
:
else
systemctl start httpd
echo at `date +”%F %T”` restart httpd >> /data/httpd.log
fi
sleep 10
done
until循环
until CONDITION; do
循环体
done
进入条件: CONDITION 为false
退出条件: CONDITION 为true
判断用户wang是否登录
[root@CENTOS7 ~]#vim wang.sh
until who | grep wang &> /dev/null ; do
sleep 1
done
echo userwang is login
循环控制语句continue
用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为
第1层
while CONDTIITON1; do
CMD1
…
if CONDITION2; then
continue
fi
CMDn
…
done
循环控制语句break
用于循环体中
break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do
CMD1
…
if CONDITION2; then
break
fi
CMDn
…
done
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue
fi
echo i=$i
done
[root@CENTOS7 ~]#./continue.sh
i=1
i=2
i=3
i=4
i=6
i=7
i=8
i=9
i=10
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
for i in {1..10}; do
if [ $i -eq 5 ]; then
break
fi
echo i=$i
done
[root@CENTOS7 ~]#./continue.sh
i=1
i=2
i=3
i=4
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
for i in {1..10}; do
for j in {1..10}; do
if [ $j -eq 5 ]; then
continue
fi
echo j=$j
done
done
~
除了j=5剩下的现实10次
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
for i in {1..10}; do
for j in {1..10}; do
if [ $j -eq 5 ]; then
continue 2
fi
echo j=$j
done
done
执行结果是j=1-4,现实10次
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
for i in {1..10}; do
for j in {1..10}; do
if [ $j -eq 5 ]; then
break
fi
echo j=$j
done
done
执行结果是j=1-4,现实10次
[root@CENTOS7 ~]#vim continue.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: continue.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..10}; do
for j in {1..10}; do
if [ $j -eq 5 ]; then
break 2
fi
echo j=$j
done
done
~
~
~
“continue.sh” 20L, 451C written
[root@CENTOS7 ~]#./continue.sh
j=1
j=2
j=3
j=4
循环控制shift命令
shift [n]
用于将参量列表 list 左移指定次数,缺省为左移一次。
参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍
历位置参量列表时,常用到 shift
./doit.sh a b c d e f g h
./shfit.sh a b c d e f g h
批量处理账号
[root@CENTOS7 ~]#vim userad.sh
#!/bin/bash
until [ -z $1 ]; do
useradd $1
echo $1 is cteatd
shift
done
echo done
[root@CENTOS7 ~]#chmod +x userad.sh
[root@CENTOS7 ~]#./userad.sh
done
[root@CENTOS7 ~]#./userad.sh a
a is cteatd
done
示例:doit.sh 1 2 3 4 5
#!/bin/bash
# Name: doit.sh
# Purpose: shift through command line arguments
# Usage: doit.sh [args]
while [ $# -gt 0 ] # or (( $# > 0 ))
do
echo $*
shift
done
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
示例:shift.sh
#!/bin/bash
#step through all the positional parameters
until [ -z “$1” ]
do
echo “$1”
shift
done
echo
创建无限循环
while true; do
循环体
done
until false; do
循环体
2、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出
[root@CENTOS7 ~]#vim guess.sh
#!/bin/bash
a=`echo $[RANDOM%11]`
while read -p “please input a nummber:” n ; do
[[ $n =~ ^[0-9]+$ ]] || { echo please input a 0-10 number ; continue ; }
if [ $n -lt $a ] ; then
echo the number less then random
elif [ $n -gt $a ];then
echo the number bigger then random
else
break
fi
done
echo is equality
特殊用法
while循环的特殊用法(遍历文件的每一行):
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
练习
扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电
话为62985600,并提示该用户的GECOS信息修改成功
取分区利用率
[root@CENTOS7 ~]#vim df.sh
#!/bin/bash
df | while read i ; do
if echo $i | grep “^/dev/sd” > /dev/null ; then
a=`echo $i | sed -r ‘s/.* ([0-9]+)%.*/\1/’`
b=`echo $i | cut -d ” ” -f1`
[ $a -gt 7 ] && echo the disk $b will be full userd $a%
fi
done
~
将/etc/passwd中uid是偶数的行显示用户和uid
[root@CENTOS7 ~]#vim uid.sh
#!/bin/bash
while read link ; do
a=`echo $link | cut -d “:” -f 3`
b=`echo $link | cut -d “:” -f 1`
let c=a%2
if [ $c -eq 0 ];then
echo $a $b
fi
done < /etc/passwd
[root@CENTOS7 ~]#./uid.sh
0 root
2 daemon
4 lp
特殊用法
双小括号方法,即((…))格式,也可以用于算术运算
双小括号方法也可以使bash Shell实现C语言风格的变量操作
I=10
((I++))
for循环的特殊格式:
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做
条件判断
[root@CENTOS7 ~]#vim sun.sh
#!/bin/bash
for (( sum=0 , i=1;$i<=100;i++ ));do
let sum=sum+i
done
echo $sum
~
[root@CENTOS7 ~]#./sun.sh
5050
select循环与菜单
select variable in list
do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在
标准错误上,并显示 PS3 提示符,等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量 REPLY 中
[root@CENTOS7 ~]#vim menu.sh
#!/bin/bash
PS3=”what do you wang to eat :”
select menu in baoyu yanwo haishen yuchi jitang ;do
case $meny in
baoyu)
echo the baoyu price is 500
break
;;
yanwo)
echo yanwo price is 1000
break
;;
haishen)
echo haoshen price is 1500
break
;;
yuchi)
echo yuchi price is 2000
break
;;
jitang)
echo jitang price is free
break
;;
esac
done
select与case
select 是个无限循环,因此要记住用 break 命令退出循环,或用
exit 命令终止脚本。也可以按 ctrl+c 退出循环
select 经常和 case 联合使用
与 for 循环类似,可以省略 in list,此时使用位置参量
信号捕捉trap
trap ‘触发指令’ 信号
自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操
作
trap ” 信号
忽略信号的操作
trap ‘-‘ 信号
恢复原信号的操作
trap -p
列出自定义信号操作
9信号在trap时不好用
kill -l 和trap -l 都可以查看信号列表
[root@CENTOS7 ~]#vim trap.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: trap.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
trap ‘echo you press Ctrl + c’ 2
for i in {1..10};do
echo $i
sleep 1
done
trap ” 2
for i in {1..10};do
echo $i
sleep 1
done
~
“trap.sh” 22L, 482C written
[root@CENTOS7 ~]#./trap.sh
1
2
^Cyou press Ctrl + c
3
[root@CENTOS7 ~]#vim trap.sh
#!/bin/bash
trap ‘echo you press Ctrl + c’ 2
trap -p
for i in {1..10};do
echo $i
sleep 1
done
trap ” 2
trap -p
for i in {1..10};do
echo $i
sleep 1
done
[[]]和[]对比
1)从概念上讲,二者是不同层次的东西
“[[“,是关键字,许多shell(如ash bsh)并不支持这种方式,ksh,bash等支持
“[“是一条命令,与test等价,大多数shell都支持;
2)[[]]结构比bash版本的[]更通用,在[[和]]之间的所有字符都不会被文件扩展或标记分割,但会有参数引用和命令替换;
用[[ … ]]测试结构比用[ … ]更能防止脚本里的许多逻辑错误;比如:&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构
会发生错误;
3)(())结构扩展并计算一个算术表达式的值;若表达式值为0,会返回1或假作为退出状态码;一个非零值的表达式返回一个0或真作为退出
状态码;这个结构跟test命令以及[]结构的讨论正好相反
4)[ … ]为shell命令,所以在其中的表达式应该是它的命令行参数,所以字符串比较操作符”>”与”<“必须转义,否则就变成了IO重定向
操作符;在[[中”<“与”>”不需转义;
5)”[[“是关键字,不会做命令行扩展,相对语法就更严格,例如:
在[ … ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ … ]]中则不允许这样做
6)[[ … ]]进行算术扩展,而[ … ]不做
1)[]和test
两者是一样的,命令行里test expr和[ expr ]效果相同;test的三个基本作用是判断文件、判断字符串、判断整数;
支持使用与或非将表达式连接起来,要注意的有:
1]test中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较;整数比较只能用-eq,-gt这
种形式;无论是字符串比较还是整数比较不要使用大于号小于号;若实在想用,可以使用尖括号的转义形式,如比较”ab”
和”bc”:[ ab \< bc ],结果为真,即返回状态为0;
2)[[]]
这是内置在shell中的一个命令:支持字符串的模式匹配,使用=~操作符支持shell的正则表达式;逻辑组合
可以不使用test的-a ,-o而使用&&,||,主要记住:
1]字符串比较时,可以把右边的作为一个模式(这是右边的字符串不加双引号的情况下,若右边字符串加了双引号,则认为是一个文本字符串)
而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真
3)使用[]和[[]]时每一项两边都要有空格,[[ 1 == 2 ]]的结果为’假’,但[[ 1==2 ]]的结果为’真’,显然后一种时错误的;
Linux组成
Linux: kernel+rootfs
kernel: 进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能 在内核包rpm -q kernel
rootfs:程序和glibc
库:函数集合, function, 调用接口(头文件负责描述)
过程调用:procedure,无返回值
函数调用:function
程序:二进制执行文件
内核设计流派:
单内核(monolithic kernel):Linux
把所有功能集成于同一个程序
微内核(micro kernel):Windows, Solaris
每种功能使用一个单独子系统实现
[root@CENTOS7 ~]#ldd /bin/ls
linux-vdso.so.1 => (0x00007ffcccfb8000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f7b92c4f000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f7b92a4a000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f7b92840000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7b9247d000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f7b9221b000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7b92016000)
/lib64/ld-linux-x86-64.so.2 (0x0000558e22dec000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f7b91e11000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7b91bf5000)
内核
Linux内核特点:
支持模块化:.ko(内核对象)
如:文件系统,硬件驱动,网络协议等
支持内核模块的动态装载和卸载
组成部分:
核心文件:/boot/vmlinuz- VERSION -release
ramdisk:辅助的伪根系统
CentOS 5: /boot/initrd- VERSION -release.img ramdisk
CentOS 6,7: /boot/initramfs- VERSION -release.img 各种和启动相关的启动模块,ramfilesystem
模块文件:/lib/modules/ VERSION -release
[root@CENTOS7 ~]#locate ext4.ko
/usr/lib/modules/3.10.0-693.el7.x86_64/kernel/fs/ext4/ext4.ko.xz
[root@CENTOS7 ~]#lsmod | grep ext4 lsmod查看内存中加载的模块
[root@CENTOS7 ~]#lsmod | grep xfs
xfs 978100 3
libcrc32c 12644 1 xfs
卸载模块 modprobe -r e1000
重要的辅助文件
[root@CENTOS7 ~]#file /boot/initramfs-3.10.0-693.el7.x86_64.img
/boot/initramfs-3.10.0-693.el7.x86_64.img: ASCII cpio archive (SVR4 with no CRC)
[root@centos6 ~]#file /boot/initramfs-2.6.32-696.el6.x86_64.img
/boot/initramfs-2.6.32-696.el6.x86_64.img: gzip compressed data, from Unix, last modified: Tue Mar 27 17:14:27 2018, max compression
解压缩
cp /boot/initramfs-2.6.32-696.el6.x86_64.img /data/boot/initramfs-2.6.32-696.el6.x86_64.img.gz
gzip -d /data/boot/initramfs-2.6.32-696.el6.x86_64.img.gz
cpio -tv < 解压后的文件
CentOS6启动流程
1.加载BIOS的硬件信息,获取第一个启动设备
2.读取第一个启动设备MBR的引导加载程序(grub)的启动信息
3.加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备
4.核心执行init程序,并获取默认的运行信息
5.init程序执行/etc/rc.d/rc.sysinit文件
6.启动核心的外挂模块
7.init执行运行的各个批处理文件(scripts)
8.init执行/etc/rc.d/rc.local
9.执行/bin/login程序,等待用户登录
10.登录之后开始以Shell控制主机
启动流程
POST:Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主
板、内存、硬盘子系统、显示子系统、串并行接口、键盘、CD-ROM光驱等硬件情况的检测。
ROM:BIOS,Basic Input and Output System,保存着有关计算机系统最重要的基本输
入输出程序,系统信息设置、开机加电自检程序和系统启动自举程序等。
RAM:CMOS互补金属氧化物半导体,保存各项参数的设定
按次序查找引导设备,第一个有引导程序的设备为本次启动设备
bootloader: 引导加载器,引导程序
windows: ntloader,仅是启动OS
Linux:功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的
内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核
LILO:LInux LOader
GRUB: GRand Unified Bootloader 宏伟统一的
GRUB 0.X: GRUB Legacy, GRUB2
启动流程 grup 安装的文件有一些放在MBR里
MBR:
446: bootloader, 64: 分区表, 2: 55AA
GRUB:
primary boot loader : 1st stage,第一扇区后面的分区存放1.5 stage ext4存放在1.5阶段
secondary boot loader :2nd stage,分区文件 放在/boot/grub 想访问/boot必须有ext4的驱动
kernel:
自身初始化:
探测可识别到的所有硬件设备
加载硬件驱动程序(借助于ramdisk加载驱动)
以只读方式挂载根文件系统 由 cat /boot/grub/grub.conf 告诉根的uuid,想挂载/需要知道/的文件系统,这个放在/boot/initramfs-2.6.32-696.el6.x86_64.img 这个文件中
运行用户空间的第一个应用程序:/sbin/init
[root@centos6 ~]#ls /boot
config-2.6.32-696.el6.x86_64 grub lost+found System.map-2.6.32-696.el6.x86_64
efi initramfs-2.6.32-696.el6.x86_64.img辅助文件,这个文件是装系统的时候生成的 symvers-2.6.32-696.el6.x86_64.gz vmlinuz-2.6.32-696.el6.x86_64 主文件,这个文件是在光盘时直接拷过来的
一但破坏initramfs-2.6.32-696.el6.x86_64.img 可以用mkinitrd /bootinitarmfs-`uname-r`.img `uname -r`来生成
ramdisk管理
ramdisk文件的制作:
(1) mkinitrd命令
为当前正在使用的内核重新制作ramdisk文件
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
(2) dracut命令
为当前正在使用的内核重新制作ramdisk文件
dracut /boot/initramfs-$(uname -r).img $(uname -r)
-r-xr-xr-x. 1 root root 4274992 Mar 29 2017 vmlinuz
[root@centos6 isolinux]#ll vmlinuz /boot/vmlinuz-2.6.32-696.el6.x86_64
-rwxr-xr-x. 1 root root 4274992 Mar 22 2017 /boot/vmlinuz-2.6.32-696.el6.x86_64
-r-xr-xr-x. 1 root root 4274992 Mar 29 2017 vmlinuz
md5sum
[root@centos6 isolinux]#md5sum vmlinuz /boot/vmlinuz-2.6.32-696.el6.x86_64
9c4cec060e29a7aa10350ca40d3f2f83 vmlinuz
9c4cec060e29a7aa10350ca40d3f2f83 /boot/vmlinuz-2.6.32-696.el6.x86_64
实验:误删除/boot/vmlinuz-3.10.0-693.el7.x86_64 修复
实验:centos6,7 上/boot/initramfs-2.6.32-696.el6.x86_64.img 损坏的修复
chroot /mnt/sysimage
mkinitrd /boot/initramfs-`uname -r`.img `uname -r`
sync
exit
exit
reboot
实验:误删除/boot/vmlinuz-3.10.0-693.el7.x86_64 修复
进入光盘启动,进入救援模式
chroot /mnt/sysimage
mkinitrd /boot/initramfs-`uname -r`.img `uname -r`
sync
sync
sync
exit
exit
reboot
误删除vmlinuz-3.10.0-693.el7.x86_64 恢复
[root@CENTOS7 boot]#rm -f vmlinuz-3.10.0-693.el7.x86_64
进入救援模式
cp /misc/cd/isolinux/vmlinuz /mnt/sysimage/boot/vmlinuz-`uname -r`
在centos6上进入救援模式后光盘没有挂载
mount /dev/sr0 /misc
等腰三角形
[root@CENTOS7 ~]#vim triangle.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-08
#FileName: triangle.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
high=$1
for i in `seq $high`;do
let wide=2*i-1
let n=$high-$i
for j in `seq $n`;do
echo -e ” \c”
done
for k in `seq $wide` ;do
echo -e “*\c”
done
echo
done
“triangle.sh” 23L, 512C written
[root@CENTOS7 ~]#./triangle.sh 5
*
***
*****
*******
*********
使用函数文件
可以将经常使用的函数存入函数文件,然后将函数文件载入shell
文件名可任意选取,但最好与相关任务有某种联系。例如:functions.main
一旦函数文件载入shell,就可以在命令行或脚本中调用函数。可以使用set命
令查看所有定义的函数,其输出列表包括已经载入shell的所有函数
若要改动函数,首先用unset命令从shell中删除函数。改动完毕后,再重新载
入此文件
创建函数文件
函数文件示例:
cat functions.main
#!/bin/bash
#functions.main
findit()
{
if [ $# -lt 1 ] ; then
echo “Usage:findit file”
return 1
fi
find / -name $1 –print
}
函数使用
函数的定义和使用:
可在交互式环境下定义函数
可将函数放在脚本文件中作为它的一部分
可放在只包含函数的单独文件中
调用:函数只有被调用才会执行
调用:给定函数名
函数名出现的地方,会被自动替换为函数代码
函数的生命周期:被调用时创建,返回时终止
[root@CENTOS7 ~]#function1 () { echo function1 ; }
[root@CENTOS7 ~]#function1
function1
[root@CENTOS7 ~]#declare -f 查看系统中定义的所有函数
[root@CENTOS7 ~]#declare -f funcion1 查看某个定义的函数
funcion1 ()
{
echo function1
}
[root@CENTOS7 ~]#function func2 () { echo func2; }
[root@CENTOS7 ~]#func2
func2
[root@CENTOS7 ~]#function func3 { echo func3; }
[root@CENTOS7 ~]#func3
func3
[root@CENTOS7 ~]#func4 () {
> echo func4
> }
[root@CENTOS7 ~]#func4
func4
[root@CENTOS7 ~]#unset func4 删除变量
[root@CENTOS7 ~]#declare -f func4
[root@CENTOS7 ~]#echo $?
1
[root@CENTOS7 ~]#less /etc/init.d/functions 这个文件中定义了很多function
[root@CENTOS7 ~]#declare -f func3
func3 ()
{
echo func3
}
[root@CENTOS7 ~]#echo $?
0
如果cmd1失败,执行cmd2和cmd3
cmd1 || { cmd1;cmd2; }其实就是一个匿名函数
如果用系统中已有的命令作为函数名,则函数名的优先级最高。高于外部命令,内部命令,别名
起函数名可以func_开头
[root@CENTOS7 ~]#unset func2 func3 funcion1 可以一次性删除多个函数
[root@CENTOS7 ~]#func1 () { name=mage;echo “func1:$name”; } 函数的生效范围是当前shell
[root@CENTOS7 ~]#func1
func1:mage
[root@CENTOS7 ~]#echo $name
mage
[root@CENTOS7 ~]#name=wang
[root@CENTOS7 ~]#func1 () { echo “func1:$name”; } 相当于name=wang ; echo “func1:$name”
[root@CENTOS7 ~]#func1
func1:wang
让函数的变量只影响自己而不影响shell
[root@CENTOS7 ~]#func1 (){ local name=mage;echo $name; } 本地变量
[root@CENTOS7 ~]#func1
mage
[root@CENTOS7 ~]#echo $name
wang
有效范围:全局变量export> 普通变量(局部变量)>本地变量
声明一个数字
[root@CENTOS7 ~]#func1 (){ declare -i name=100;echo $name; } declare -i 默认就是本地变量想要其生成普通变量declare -ig在centos7上支持,在centos6上不支持
[root@CENTOS7 ~]#func1
100
[root@CENTOS7 ~]#echo $name
wang
[root@CENTOS7 ~]#func1 (){ declare -ig name=100;echo $name; }
[root@CENTOS7 ~]#func1
100
[root@CENTOS7 ~]#echo $name
100
[root@CENTOS7 bin]#vim redyel.sh 这个函数只能打印红黄用加参数如 -r 来让函数可以显示黄红
#!/bin/bash
redyel(){
echo -e “\033[1;41m \033[1;42m \033[0m”
}
redyel
[root@CENTOS7 bin]#chmod +x redyel.sh
[root@CENTOS7 bin]#redyel.sh
函数后面也可以加位置参数用法和脚本的一样
[root@CENTOS7 bin]#func1 () { echo arg1:$1;echo arg2:$2;echo arg@:$@;echo arg#:$#; }
[root@CENTOS7 bin]#func1
arg1:
arg2:
arg@:
arg#:0
[root@CENTOS7 bin]#func1 a b c d
arg1:a
arg2:b
arg@:a b c d
arg#:4
[root@CENTOS7 bin]#vim redyel.sh return退出当前函数
#!/bin/bash
redyel(){
if [ “$1” = “-r” ];then
echo -e “\033[1;42m \033[1;41m \033[0m”
return
fi
echo -e “\033[1;41m \033[1;42m \033[0m”
}
redyel
redyel -r
[root@CENTOS7 ~]#version () { ver=`cat /etc/centos-release | sed -r ‘s/.* ([0-9]+)\..*/\1/’` ;echo $ver; }[root@CENTOS7 ~]#version
7
if [ `version` -eq 6 ];then
echo version is old
else echo cersion is new
fi
cersion is new
[root@CENTOS7 ~]#add (){ echo $[$1+$2]; }
[root@CENTOS7 ~]#add 1 2
3
[root@CENTOS7 ~]#add 5 6
11
函数返回值
函数有两种返回值:
函数的执行结果返回值:
(1) 使用echo等命令进行输出
(2) 函数体中调用命令的输出结果
函数的退出状态码:
(1) 默认取决于函数中执行的最后一条命令的退出状态码
(2) 自定义退出状态码,其格式为:
return 从函数中返回,用最后状态命令决定返回值 return 只能在函数中使用
return 0 无错误返回。
return 1-255 有错误返回
[root@CENTOS7 ~]#return
-bash: return: can only `return’ from a function or sourced script
交互式环境下定义和使用函数
示例:
dir() {
> ls -l
> }
定义该函数后,若在$后面键入dir,其显示结果同ls -l的作用相同
dir
该dir函数将一直保留到用户从系统退出,或执行了如下所示的unset命令
unset dir
在脚本中定义及使用函数
函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它
后才能使用
调用函数仅使用其函数名即可
示例:
cat func1
#!/bin/bash
# func1
hello()
{
echo “Hello there today’s date is `date +%F`”
}
echo “now going to the function hello”
hello
echo “back from the function”
使用函数文件
可以将经常使用的函数存入函数文件,然后将函数文件载入shell
文件名可任意选取,但最好与相关任务有某种联系。例如:functions.main
一旦函数文件载入shell,就可以在命令行或脚本中调用函数。可以使用set命
令查看所有定义的函数,其输出列表包括已经载入shell的所有函数
若要改动函数,首先用unset命令从shell中删除函数。改动完毕后,再重新载
入此文件
[root@CENTOS7 ~]#vim function 将函数放入一个文本文件中
#!/bin/bash
version () { ver=`cat /etc/centos-release | sed -r ‘s/.* ([0-9]+)\..*/\1/’` ;echo $ver; }
redyel(){
if [ “$1” = “-r” ];then
echo -e “\033[1;42m \033[1;41m \033[0m”
return
fi
echo -e “\033[1;41m \033[1;42m \033[0m”
[root@CENTOS7 ~]#vim f3.sh 在脚本中调用写好的函数
#!/bin/bash
source function
version
redyel
[root@CENTOS7 ~]#bash f3.sh
7
[root@CENTOS7 ~]#ls /etc/init.d 系统中就是把函数写在functions中,在脚本中调用些函数。
functions netconsole network README
[root@CENTOS7 ~]#ll /etc/init.d/functions /etc/rc.d/init.d/functions
-rw-r–r–. 1 root root 17500 May 3 2017 /etc/init.d/functions
-rw-r–r–. 1 root root 17500 May 3 2017 /etc/rc.d/init.d/functions
[root@CENTOS7 ~]#ll -d /etc/init.d /etc/rc.d/init.d
lrwxrwxrwx. 1 root root 11 Mar 27 17:54 /etc/init.d -> rc.d/init.d
drwxr-xr-x. 2 root root 70 Mar 27 17:56 /etc/rc.d/init.d
载入函数
函数文件已创建好后,要将它载入shell
定位函数文件并载入shell的格式
. filename 或 source filename
注意:此即<点> <空格> <文件名>
这里的文件名要带正确路径
示例:
上例中的函数,可使用如下命令:
. functions.main
[root@CENTOS7 ~]#. /etc/init.d/functions 调用系统自带函数
[root@CENTOS7 ~]#action “command successful” 系统自带函数中的action作用
command successful [ OK ]
[root@CENTOS7 ~]#action “command successful” /bin/false
command successful [FAILED]
[root@CENTOS7 ~]#action “command successful” /bin/true
command successful [ OK ]
如果已经调用的函数修改了函数的内容应该再次引用source function
检查载入函数
使用set命令检查函数是否已载入。set命令将在shell中显示所有的载入函数
示例:
set
findit=( )
{
if [ $# -lt 1 ]; then
echo “usage :findit file”;
return 1
fi
find / -name $1 -print
}
…
执行shell函数
要执行函数,简单地键入函数名即可
示例:
findit groups
/usr/bin/groups
/usr/local/backups/groups.bak
删除shell函数
现在对函数做一些改动后,需要先删除函数,使其对shell不可用。使用unset命
令完成删除函数
命令格式为:
unset function_name
示例:
unset findit
再键入set命令,函数将不再显示
环境函数
使子进程也可使用
声明:export -f function_name
查看:export -f 或 declare -xf
函数参数
函数可以接受参数:
传递参数给函数:调用函数时,在函数名后面以空白分隔给定参数列表即可;
例如“testfunc arg1 arg2 …”
在函数体中当中,可使用$1, $2, …调用这些参数;还可以使用$@, $*, $#
等特殊变量
[root@CENTOS7 ~]#export -f func1 将普通函数定义成全局函数
[root@CENTOS7 ~]#bash
[root@CENTOS7 ~]#func1
func1
[root@CENTOS7 ~]#expotr -f func2 () { echo func2 ; } 不可以直接定义一个正在创建的函数
-bash: syntax error near unexpected token `(‘
函数变量
变量作用域:
环境变量:当前shell和子shell有效 全局变量
本地变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程; 普通变量
因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数
局部变量:函数的生命周期;函数结束时变量被自动销毁 本地变量
注意:如果函数中有局部变量,如果其名称同本地变量,使 用局部变量
在函数中定义局部变量的方法
local NAME=VALUE
函数递归示例
函数递归:
函数直接或间接调用自身
注意递归层数
递归实例:
阶乘是基斯顿·卡曼于 1808 年发明的运算符号,是数学术语
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且有0的
阶乘为1,自然数n的阶乘写作n!
n!=1×2×3×…×n
阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n
n!=n(n-1)(n-2)…1
n(n-1)! = n(n-1)(n-2)!
[root@CENTOS7 ~]#func1 () { let i++;echo $i;echo func1;func1; }
这个数会不断的累加直到机器死机,这些数会加载到内存中,中断执行后继续执行,会接着上次的执行结果继续执行
函数递归示例
示例:fact.sh 如果$1是一个负数这无限循环
#!/bin/bash
#
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1
fork炸弹
fork炸弹是一种恶意程序,它的内部是一个不断在fork进程的无限循环,实质是
一个简单的递归程序。由于程序是递归的,如果没有任何限制,这会导致这个
简单的程序迅速耗尽系统里面的所有资源
函数实现
:(){ :|:& };:
bomb() { bomb | bomb & }; bomb
脚本实现
cat Bomb.sh
#!/bin/bash
./$0|./$0&
系统启动流程
init程序的类型:
SysV: init, CentOS 5之前
配置文件:/etc/inittab redhat
Upstart: init,CentOS 6
配置文件:/etc/inittab, /etc/init/*.conf
Systemd:systemd, CentOS 7 ubantu
配置文件:/usr/lib/systemd/system
/etc/systemd/system redhat
启动流程
/sbin/init CentOS6之前
运行级别:为系统运行或维护等目的而设定;0-6:7个级别
0:关机
1:单用户模式(root自动登录), single, 维护模式
2: 多用户模式,启动网络功能,但不会启动NFS;维护模式
3:多用户模式,正常模式;文本界面
4:预留级别;可同3级别
5:多用户模式,正常模式;图形界面
6:重启
默认级别: 3, 5
切换级别:init #
查看级别:runlevel ; who -r
init初始化
init读取其初始化文件:/etc/inittab
初始运行级别(RUN LEVEL)
系统初始化脚本
对应运行级别的脚本目录
捕获某个关键字顺序
定义UPS电源终端/恢复脚本
在虚拟控制台生成getty
在运行级别5初始化X
[root@centos6 ~]#cat /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 – halt (Do NOT set initdefault to this)
# 1 – Single user mode
# 2 – Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 – Full multiuser mode
# 4 – unused
# 5 – X11
# 6 – reboot (Do NOT set initdefault to this)
#
id:5:initdefault: id表示这个行的名字 5 模式 initdefault默认模式
id:6:initdefault: 设置成6的话会无限重启
解决办法 在重启是按任意键,在选择启动系统的地方按a键然后 (1,3,5)进入你想进的模式,在这选择模式后不会读取/etc/inittan文件。
1模式可以重新设置口令,进入1模式后身份是root
直接passwd重置口令就可以了
[root@centos6 ~]#cat /etc/rc.d/rc.sysinit 初始化的第一个脚本
#!/bin/bash
#
# /etc/rc.d/rc.sysinit – run once at boot time
#
# Taken in part from Miquel van Smoorenburg’s bcheckrc.
#
HOSTNAME=$(/bin/hostname)
set -m
if [ -f /etc/sysconfig/network ]; then
. /etc/sysconfig/network
fi
if [ -z “$HOSTNAME” -o “$HOSTNAME” = “(none)” ]; then
HOSTNAME=localhost
fi
启动流程
/etc/rc.d/rc.sysinit: 系统初始化脚本
(1) 设置主机名
(2) 设置欢迎信息
(3) 激活udev和selinux
(4) 挂载/etc/fstab文件中定义的文件系统
(5) 检测根文件系统,并以读写方式重新挂载根文件系统
(6) 设置系统时钟
(7) 激活swap设备
(8) 根据/etc/sysctl.conf文件设置内核参数
(9) 激活lvm及software raid设备
(10) 加载额外设备的驱动程序
(11) 清理操作
CentOS 5的inittab文件
配置文件:/etc/inittab
每一行定义一种action以及与之对应的process
id:runlevel:action:process
action:
wait: 切换至此级别运行一次
respawn:此process终止,就重新启动之
initdefault:设定默认运行级别;process省略
sysinit:设定系统初始化方式,此处一般为指定
/etc/rc.d/rc.sysinit
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1…
l6:6:wait:/etc/rc.d/rc 6
进入5模式后
for i in /etc/rc$runlevel.d/S* ; do
# Check if the subsystem is already up.
subsys=${i#/etc/rc$runlevel.d/S??}
[ -f /var/lock/subsys/$subsys ] && continue
[ -f /var/lock/subsys/$subsys.init ] && continue
check_runlevel “$i” || continue
# If we’re in confirmation mode, get user confirmation
if [ “$do_confirm” = “yes” ]; then
confirm $subsys
rc=$?
if [ “$rc” = “1” ]; then
continue
elif [ “$rc” = “2” ]; then
do_confirm=”no”
fi
fi
选着进入/etc/rc5.d 先运行K开头的并stop在运行S开头的文件并start
[root@centos6 ~]#ls /etc/rc5.d 根据文件名的顺序执行
K01smartd K60nfs K95firstboot S22messagebus S55sshd
K02oddjobd K61nfs-rdma K99rngd S23NetworkManager S58ntpd
K05wdaemon K69rpcsvcgssd S01sysstat S24nfslock S70spice-vdagentd
K10psacct K73winbind S02lvm2-monitor S24openct S80postfix
K10saslauthd K75ntpdate S05rdma S24rpcgssd S82abrtd
K15htcacheclean K75quota_nld S08ip6tables S25blk-availability S83abrt-ccpp
K15httpd K76ypbind S10network S25cups S90crond
K15svnserve K84wpa_supplicant S11auditd S25netfs S95atd
K35nmb K87restorecond S11portreserve S26acpid S99certmonger
K35smb K88sssd S12rsyslog S26haldaemon S99local
K36mysqld K89netconsole S13cpuspeed S26udev-post
K50dnsmasq K89rdisc S13irqbalance S27pcscd
K50kdump K92iptables S13rpcbind S28autofs
K50vsftpd K92pppoe-server S15mdmonitor S50bluetooth
[root@centos6 ~]#/etc/rc5.d/K01smartd stop 可以这样停止程序
Shutting down smartd: [FAILED]
相当于
[root@centos6 ~]#service smartd stop
Shutting down smartd: [FAILED]
这些服务分为:
独立服务:不依赖于别人的服务
[root@centos6 ~]#ls /etc/init.d /etc/rc5.d中的服务是这个文件夹下的服务的软连接
abrt-ccpp dnsmasq lvm2-monitor ntpdate rpcbind svnserve
abrtd firstboot mdmonitor oddjobd rpcgssd sysstat
abrt-oops functions messagebus openct rpcidmapd udev-post
acpid haldaemon mysqld pcscd rpcsvcgssd vsftpd
atd halt netconsole portreserve rsyslog wdaemon
auditd htcacheclean netfs postfix sandbox winbind
autofs httpd network pppoe-server saslauthd wpa_supplicant
blk-availability ip6tables NetworkManager psacct single ypbind
bluetooth iptables nfs quota_nld smartd
certmonger irqbalance nfslock rdisc smb
cpuspeed kdump nfs-rdma rdma spice-vdagentd
crond killall nmb restorecond sshd
cups lvm2-lvmetad ntpd rngd sssd
之前定义的计划任务cron @reboot root reboot 进入后就会无限重启
之所以进入1模式可以进行修改是因为在5模式的时候cron默认是开机启动而在
1模式的时候cron默认开机不启动
查看5模式下开机启动项
ntsysv –level=5
在这个命令界面下 去掉点*就是修改/etc/rc5.d中的软连接文件夹的名字来完成对开机启动项的默认修改
也可以直接修改/etc/rc5.d/中的软连接的名字来直接更改启动开启项
列如mv /etc/rc5.d/K05atd /etc/rc5.d/S95atd
ntsysv –level=3
去掉 atd *
atd就变成K开头的
[root@centos6 ~]#ls /etc/rc3.d/
K01smartd K35nmb K76ypbind S02lvm2-monitor S15mdmonitor S27pcscd
K02oddjobd K35smb K87restorecond S05rdma S19rpcgssd S28autofs
K05atd K36mysqld K88sssd S08ip6tables S22messagebus S50bluetooth
K05wdaemon K50dnsmasq K88wpa_supplicant S10network S23NetworkManager S55sshd
K100kdump K50vsftpd K89netconsole S11auditd S24openct S58ntpd
K10psacct K60nfs K89rdisc S11portreserve S25blk-availability S80postfix
K10saslauthd K61nfs-rdma K92iptables S12rsyslog S25cups S82abrt-ccpp
K15htcacheclean K69rpcsvcgssd K92pppoe-server S13cpuspeed S25netfs S82abrtd
K15httpd K73winbind K95firstboot S13irqbalance S26acpid S90crond
K15svnserve K75ntpdate K99rngd S13rpcbind S26haldaemon S99certmonger
K30spice-vdagentd K75quota_nld S01sysstat S14nfslock S26udev-post
[root@centos6 ~]#chkconfig –list atd 查看所有模式下atd默认启动情况
atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off
[root@centos6 ~]#chkconfig –level=35 atd off 将3,5模式的默认设置改变
[root@centos6 ~]#chkconfig –list atd
atd 0:off 1:off 2:off 3:off 4:on 5:off 6:off
[root@centos6 ~]#chkconfig atd off
[root@centos6 ~]#chkconfig atd on
[root@centos6 ~]#chkconfig –list atd 默认开启或者关闭的是2,3,4,5模式
atd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
禁止防火墙启动
chkconfig iptables off
K开头的文件在系统启动的时候是根本不启动的,如何判断这个程序起没启动
[ -f/var/lock/subsys ]
但是如果是init3来切换模式则有可能这个文件是已经启动的,因此还要执行后续命令 stop
[root@centos6 ~]#ll /var/lock/subsys 这里就是放个文件名,文件根本没有内容
total 0
-rw-r–r–. 1 root root 0 May 10 08:59 abrt-ccpp
-rw-r–r–. 1 root root 0 May 10 08:59 abrtd
-rw-r–r–. 1 root root 0 May 10 08:59 acpid
-rw-r–r–. 1 root root 0 May 10 08:59 atd
-rw-r–r–. 1 root root 0 May 10 08:59 auditd
-rw-r–r–. 1 root root 0 May 10 08:59 autofs
-rw-r–r–. 1 root root 0 May 10 08:59 blk-availability
-rw-r–r–. 1 root root 0 May 10 08:59 certmonger
-rw-r–r–. 1 root root 0 May 10 08:59 crond
-rw-r–r–. 1 root root 0 May 10 08:59 cups
-rw-r–r–. 1 root root 0 May 10 08:59 haldaemon
-rw-r–r–. 1 root root 0 May 10 08:58 ip6tables
-rw-r–r–. 1 root root 0 May 10 08:59 local
-rw-r–r–. 1 root root 0 May 10 08:58 lvm2-monitor
-rw-r–r–. 1 root root 0 May 10 08:59 messagebus
-rw-r–r–. 1 root root 0 May 10 08:59 netfs
-rw-r–r–. 1 root root 0 May 10 08:58 network
-rw-r–r–. 1 root root 0 May 10 08:59 NetworkManager
-rw-r–r–. 1 root root 0 May 10 08:59 ntpd
-rw-r–r–. 1 root root 0 May 10 08:59 openct
-rw——-. 1 root root 0 May 10 08:59 pcscd
-rw-r–r–. 1 root root 0 May 10 08:59 postfix
-rw-r–r–. 1 root root 0 May 10 08:58 rdma
-rw-r–r–. 1 root root 0 May 10 08:59 rpcbind
-rw-r–r–. 1 root root 0 May 10 08:59 rpc.statd
-rw——-. 1 root root 0 May 10 08:59 rsyslog
-rw-r–r–. 1 root root 0 May 10 08:59 sshd
[root@centos6 ~]#ls /etc/rc5.d 服务的前后顺序很重要,因为后面的服务有可能依赖前面的服务,因此当自己写了一个服务的时候应尽量往后放,不是按数字排序而是按字符次序排序。
K01smartd K60nfs K95firstboot S22messagebus S55sshd
K02oddjobd K61nfs-rdma K99rngd S23NetworkManager S58ntpd
K05wdaemon K69rpcsvcgssd S01sysstat S24nfslock S70spice-vdagentd
K10psacct K73winbind S02lvm2-monitor S24openct S80postfix
K10saslauthd K75ntpdate S05rdma S24rpcgssd S82abrtd
K15htcacheclean K75quota_nld S08ip6tables S25blk-availability S83abrt-ccpp
K15httpd K76ypbind S10network S25cups S90crond
K15svnserve K84wpa_supplicant S11auditd S25netfs S95atd
K35nmb K87restorecond S11portreserve S26acpid S99certmonger
K35smb K88sssd S12rsyslog S26haldaemon S99local
K36mysqld K89netconsole S13cpuspeed S26udev-post
K50dnsmasq K89rdisc S13irqbalance S27pcscd
K50kdump K92iptables S13rpcbind S28autofs
K50vsftpd K92pppoe-server S15mdmonitor S50bluetooth
S开头的文件顺序越靠前则在K开头的文件里顺序就越靠后,反之依然。
.
CentOS 6 /etc/inittab和相关文件
/etc/inittab
设置系统默认的运行级别
id:3:initdefault:
示例:
破解CentOS5和6的root口令
/etc/init/control-alt-delete.conf
/etc/init/tty.conf
/etc/init/start-ttys.conf
/etc/init/rc.conf
/etc/init/prefdm.conf
启动流程
说明:rc N –> 意味着读取/etc/rc.d/rcN.d/
K*: K##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为
依赖到别的服务
S*: S##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为
被依赖到的服务
for srv in /etc/rc.d/rcN.d/K*; do
$srv stop
done
for srv in /etc/rc.d/rcN.d/S*; do
$srv start
done
chkconfig命令
chkconfig命令
查看服务在所有级别的启动或关闭设定情形:
chkconfig [–list] [name]
添加:
SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)
chkconfig –add name
#!/bin/bash
#LLLL 表示初始在哪个级别下启动,-表示都不启动
# chkconfig: LLLL nn nn
删除:
chkconfig –del name
修改指定的链接类型
chkconfig [–level levels] name <on|off|reset>
–level LLLL: 指定要设置的级别;省略时表示2345
ntsysv命令
xinetd管理的服务
service 命令:手动管理服务
service 服务 start|stop|restart
service –status-all
瞬态(Transient)服务被xinetd进程所管理
进入的请求首先被xinetd代理
配置文件:/etc/xinetd.conf、/etc/xinetd.d/<service>
与libwrap.so文件链接
用chkconfig控制的服务:
chkconfig tftp on
启动流程
注意:正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个
服务脚本,而是指向了/etc/rc.d/rc.local脚本
不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行
的命令,可直接放置于/etc/rc.d/rc.local文件中
/etc/rc.d/rc.local在指定运行级别脚本后运行
可以根据情况,进行自定义修改
启动流程
1:2345:respawn:/usr/sbin/mingetty tty1
2:2345:respawn:/usr/sbin/mingetty tty2
…
6:2345:respawn:/usr/sbin/mingetty tty6
mingetty会自动调用login程序
x:5:respawn:/etc/X11/prefdm -nodaemon
启动过程
总结:/sbin/init –> (/etc/inittab) –> 设置默认运行级别 –> 运行系统初始
脚本、完成系统初始化 –> (关闭对应下需要关闭的服务)启动需要启动服务 —
> 设置登录终端
CentOS 6 init程序为: upstart, 其配置文件:
/etc/inittab, /etc/init/*.conf,配置文件的语法 遵循 upstart配置文件语
法格式,和CentOS5不同
自定义一个开机开启或者关闭的服务
在文件夹/etc/init.d中加入一个脚本,脚本格式是
[root@centos6 init.d]#cat atd
#!/bin/sh
# chkconfig: 345 95 5 345 代表在上面模式下开机启动 95是S文件的开启次序,5是K的关闭次序
#chkconfig : – 96 4 代表所有模式都是开启的
在/etc/init.d/文件夹下
vim testsev 模拟一个服务,
#!/bin/bash
#chkconfig: 35 96 3
#description: test service
. /etc/init.d/functions
case $1 in
start)
action ” testservice is starting”
touch /var/lock/subsys/testservice
;;
stop) rm -f /var/lock/subsys/testservice
action “testservice is stopped”
;;
status)
[ -f /var/lock/subsys/testservice ] && echo testservice is running || echo testservice is stopped
;;
*)
echo “usage: service testservice start|stop|status”
;;
esac
虽然开启了服务,但是这个服务并没有加入到3 和 5 模式中 所以chkconfig –list 看不到这个服务
[root@centos6 init.d]#./testservice start
testservice is starting [ OK ]
[root@centos6 init.d]#chkconfig –list
[root@centos6 init.d]#chkconfig –add testservice 将这个服务添加进相应的模式中
[root@centos6 init.d]#chkconfig –add testservice
[root@centos6 init.d]#chkconfig –list testservice
testservice 0:off 1:off 2:off 3:on 4:off 5:on 6:off
[root@centos6 init.d]#ls /etc/rc5.d
K01smartd K60nfs K95firstboot S22messagebus S55sshd
K02oddjobd K61nfs-rdma K99rngd S23NetworkManager S58ntpd
K05wdaemon K69rpcsvcgssd S01sysstat S24nfslock S70spice-vdagentd
K10psacct K73winbind S02lvm2-monitor S24openct S80postfix
K10saslauthd K75ntpdate S05rdma S24rpcgssd S82abrtd
K15htcacheclean K75quota_nld S08ip6tables S25blk-availability S83abrt-ccpp
K15httpd K76ypbind S10network S25cups S90crond
K15svnserve K84wpa_supplicant S11auditd S25netfs S95atd
K35nmb K87restorecond S11portreserve S26acpid S96testservice
K35smb K88sssd S12rsyslog S26haldaemon S99certmonger
K36mysqld K89netconsole S13cpuspeed S26udev-post S99local
K50dnsmasq K89rdisc S13irqbalance S27pcscd
K50kdump K92iptables S13rpcbind S28autofs
K50vsftpd K92pppoe-server S15mdmonitor S50bluetooth
[root@centos6 init.d]#chkconfig –level 5 testservice off
[root@centos6 init.d]#ls /etc/rc5.d
K01smartd K50vsftpd K92pppoe-server S15mdmonitor S50bluetooth
K02oddjobd K60nfs K95firstboot S22messagebus S55sshd
K03testservice K61nfs-rdma K99rngd S23NetworkManager S58ntpd
K05wdaemon K69rpcsvcgssd S01sysstat S24nfslock S70spice-vdagentd
K10psacct K73winbind S02lvm2-monitor S24openct S80postfix
K10saslauthd K75ntpdate S05rdma S24rpcgssd S82abrtd
K15htcacheclean K75quota_nld S08ip6tables S25blk-availability S83abrt-ccpp
K15httpd K76ypbind S10network S25cups S90crond
K15svnserve K84wpa_supplicant S11auditd S25netfs S95atd
K35nmb K87restorecond S11portreserve S26acpid S99certmonger
K35smb K88sssd S12rsyslog S26haldaemon S99local
K36mysqld K89netconsole S13cpuspeed S26udev-post
K50dnsmasq K89rdisc S13irqbalance S27pcscd
K50kdump K92iptables S13rpcbind S28autofs
删除这个服务脚本
chkconfig –del
[root@centos6 init.d]#chkconfig –list
NetworkManager 0:off 1:off 2:on 3:on 4:on 5:on 6:off
sysstat 0:off 1:on 2:on 3:on 4:on 5:on 6:off
testservice 0:off 1:off 2:off 3:on 4:off 5:on 6:off
udev-post 0:off 1:on 2:on 3:on 4:on 5:on 6:off
[root@centos6 init.d]#chkconfig –del testservice 从服务中删除这个脚本,这个删除只是删除了/etc/rc5.d/中的K和S开头的文件,
但是在/etc/init.d中的testservice并没有删除
[root@centos6 init.d]#chkconfig –list
sysstat 0:off 1:on 2:on 3:on 4:on 5:on 6:off
udev-post 0:off 1:on 2:on 3:on 4:on 5:on 6:off
vsftpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
在centos6及之前的版本,在/etc/rc(2-5).d中都有S99lacal,这个文件是最后执行,如果想开机启动也可将命令或者脚本放到这个文件中
在centos7上这个文件没有执行权限,如果想用要先加执行权限。
[root@centos6 init.d]#service –status-all 查看看所有的服务状态
abrt-ccpp hook is installed
abrtd (pid 2861) is running…
abrt-dump-oops is stopped
acpid (pid 2589) is running…
非独立服务:
xinetd管理的服务
service 命令:手动管理服务
service 服务 start|stop|restart
service –status-all
瞬态(Transient)服务被xinetd进程所管理
进入的请求首先被xinetd代理
配置文件:/etc/xinetd.conf、/etc/xinetd.d/<service>
与libwrap.so文件链接
用chkconfig控制的服务:
chkconfig tftp on
在centos6及之前的版本:
安装telnet service服务会自动安装xinetd服务
xinetd服务是独立服务但是telnet不是,telnet由xinetd来监听
如果有人用telnet服务则唤醒telnet,否则telnet服务处于sleep状态,
[root@centos6 ~]#service xinetd start
Starting xinetd: [ OK ]
[root@centos6 ~]#chkconfig –list
xinetd based services:
chargen-dgram: off
chargen-stream:off
daytime-dgram: off
daytime-stream:off
discard-dgram: off
discard-stream:off
echo-dgram: off
echo-stream: off
rsync: off
tcpmux-server: off
telnet: off
time-dgram: off
time-stream: off
[root@centos6 ~]#chkconfig –level 5 telnet on
[root@centos6 ~]#chkconfig –list
xinetd based services:
chargen-dgram: off
chargen-stream:off
daytime-dgram: off
daytime-stream:off
discard-dgram: off
discard-stream:off
echo-dgram: off
echo-stream: off
rsync: off
tcpmux-server: off
telnet: on
time-dgram: off
time-stream: off
[root@centos6 ~]#ss -ntlpe 无人访问时由xinetd来监听,一但有人访问则唤醒telnet由telnet来建立连接
LISTEN 0 64 :::23 :::* users:((“xinetd”,5874,5)) ino:28132 sk:ffff88007c2a5040
users:((“xinetd”,5874,5)) ino:28132 sk:ffff88007c2a5040
在centos7很多的服务都是非独立服务,因为systemd来监听所有服务。
[root@centos6 ~]#vim /etc/init/control-alt-delete.conf 注释掉#exec /sbin/shutdown -r now “Control-Alt-Delete pressed”
防止误操作重启
# control-alt-delete – emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed. Usually used to shut down the machine.
#
# Do not edit this file directly. If you want to change the behaviour,
# please create a file control-alt-delete.override and put your changes there.
start on control-alt-delete
#exec /sbin/shutdown -r now “Control-Alt-Delete pressed”
启动过程:
bois自检,MBR grub 内核 通过grub读取内核文件加载/分区,/sbin/init –> (/etc/inittab) –> 设置默认运行级别 –> 运行系统初始
脚本、完成系统初始化 –> (关闭对应下需要关闭的服务)启动需要启动服务 –,>设置终端登录
CentOS 6启动流程:
POST –> Boot Sequence(BIOS) –> Boot Loader –> Kernel(ramdisk) –>
rootfs –> switchroot –> /sbin/init –>(/etc/inittab, /etc/init/*.conf) –> 设定默认
运行级别 –> 系统初始化脚本 rc.sysinit –> 关闭或启动对应级别的服务 –> 启动终端
grub legacy :
grub: GRand Unified Bootloader
grub 0.97: grub legacy
grub 2.x: grub2
grub legacy:
stage1: mbr
stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所
在的分区上的文件系统
stage2:磁盘分区(/boot/grub/)
禁用selinux
centos7
[root@centos6 ~]#vim /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing – SELinux security policy is enforced.
# permissive – SELinux prints warnings instead of enforcing.
# disabled – No SELinux policy is loaded.
SELINUX=enforcing 将enforcing 改成disabled
# SELINUXTYPE= can take one of these two values:
# targeted – Targeted processes are protected,
# mls – Multi Level Security protection.
SELINUXTYPE=targeted
[root@centos6 ~]#hexdump -C /dev/sda -n 512 -v
00000000 eb 48 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 |.H…………..|
00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |…|………!..|
如果dd if=/dev/sda of=/data/dd bs=1 count=512
sz /data/dd
删除/dev/sda 第一扇区的446个字节
dd if=/dev/zero of=/dev/sda bs=1 count=446
reboot
发现直接进入光盘模式,因为系统发现硬盘无法引导
进入救援模式
chroot /mnt/sysimage
dd if=/data/dd of=/dev/sda bs=1 count=446
sync
sync
sync
reboot
grub安装
安装grub:
(1) grub-install
安装grub stage1和stage1_5到/dev/DISK磁盘上,并复制GRUB相关文件
到 DIR/boot目录下
grub-install –root-directory=DIR /dev/DISK
(2) grub
grub> root (hd#,#)
grub> setup (hd#)
用grub-install命令修复
dd if=/dev/zero of=/dev/sda bs=1 count=446
reboot
发现直接进入光盘模式,因为系统发现硬盘无法引导
进入救援模式
chroot /mnt/sysimage
grub-install
sync
sync
sync
exit
exit
reboot
用grub>root (hd0,0) 修复
dd if=/dev/zero of=/dev/sda bs=1 count=446
[root@centos6 ~]#dd if=/dev/zero of=/dev/sda bs=1 count=446
446+0 records in
446+0 records out
446 bytes (446 B) copied, 0.000583095 s, 765 kB/s
[root@centos6 ~]#hexdump -C /dev/sda -n 512 -v
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
[root@centos6 ~]#grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
grub> root (hd0,0)
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)
setup (hd0)
Checking if “/boot/grub/stage1” exists… no
Checking if “/grub/stage1” exists… yes
Checking if “/grub/stage2” exists… yes
Checking if “/grub/e2fs_stage1_5” exists… yes
Running “embed /grub/e2fs_stage1_5 (hd0)”… 27 sectors are embedded. grub1.5阶段放在了mbr后面的27个扇区
succeeded
Running “install /grub/stage1 (hd0) (hd0)1+27 p (hd0,0)/grub/stage2 /grub/grub.conf”… succeeded
Done.
grup 修复的时候依赖于/boot/grub/中的文件如果移走除了splash.xpm.gz和grub.conf 的其他文件,不影响启动但是无法再使用grub交互式的方式修复受损的启动引导磁盘
grub-install命令不依赖上面的文件及时移走一样能够修复而且可以生成文件夹中移走的文件
破坏grub1.5阶段也就是破坏mbr后面的27个扇区。
dd if=/dev/zero of=/dev/sda bs=1 count=10000 skip=512 seek=512
出现的故障是进入不了菜单,不是直接光盘引导,因为没有破坏硬盘的512个字节
系统默认硬盘可以引导。
进入救援模式
chroot /mnt/sysimage
grub-install
sync
…
破坏了1.5阶段后,用grub命令交互式修复后,如果再移走/boot/grub中的文件,则导致电脑无法启动
修复方法
进入救援模式
chroot /mnt/sysimage
将移走的文件在拷回/boot/grub中
[root@centos6 ~]#cat /boot/grub/grub.conf grub.conf是grub在第二阶段重要的配置文件
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-696.el6.x86_64) 引导系统的菜单项
root (hd0,0)
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=408b65d7-7551-480b-8916-5eff4cca1b00 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet max_loop=100
initrd /initramfs-2.6.32-696.el6.x86_64.img
[root@centos6 ~]#vim /boot/grub/grub.conf
# grub.conf generated by anaconda
# i
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-696.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=408b65d7-7551-480b-8916-5eff4cca1b00 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet max_loop=100
initrd /initramfs-2.6.32-696.el6.x86_64.img
title CentOS 100 (linux wang) 复制上面的文件然后修改可以看到两个启动可选菜单
kernel (hd0,0)/vmlinuz-2.6.32-696.el6.x86_64 找到主启动文件后,找/然后以制度方式挂载ro root=UUID=408b65d7-7551-480b-8916-5eff4cca1b00其后会二次挂载二次挂载时就是rw模式挂载。
rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet max_loop=100
initrd (hd0,0)/initramfs-2.6.32-696.el6.x86_64.img
[root@centos6 ~]#vim /boot/grub/grub.conf
# grub.conf generated by anaconda
# i
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0 默认启动centos6,0代表第一个title
timeout=5 停滞5秒以供选择
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu 默认隐藏,所以需要敲任意键才能显示菜单。
title root (hd0,0)
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=408b65d7-7551-480b-8916-5eff4cca1b00 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet max_loop=100
initrd /initramfs-2.6.32-696.el6.x86_64.img
title CentOS 100 (linux wang)
kernel (hd0,0)/vmlinuz-2.6.32-696.el6.x86_64 root=/dev/sda2 这两行的顺序不能颠倒 必须 kernel在前initd在后。
initrd (hd0,0)/initramfs-2.6.32-696.el6.x86_64.img
quiet 是否显示内核启动过程 rhgb启动时是否是图形界面
如果这kernel (hd0,0)/vmlinuz-2.6.32-696.el6.x86_64 root=/dev/sda2
initrd (hd0,0)/initramfs-2.6.32-696.el6.x86_64.img
写反了,那么重启将失败,修复方法e编辑d删除o开启新航e编辑:添加initrd/initramfs-2.6.32-696.el6.x86_64.img支持TAB键补全。然后按b重新启动
这是临时修改,等机器启动起来后再去配置文件中将两行的次序调整好。
[root@centos6 ~]#cp /boot/grub/splash.xpm.gz /data 将splash.xpm.gz这个文件拷贝到/data下
[root@centos6 data]#ls
beifen f1 f3 loop8 mbr_bak raid sdb2 splash.xpm.gz TRANS.TBL
dd f2 install.sh mbr_backup mm sdb1 sdb3 src
[root@centos6 data]#gunzip splash.xpm.gz 解压
[root@centos6 data]#ls
beifen f1 f3 loop8 mbr_bak raid sdb2 splash.xpm TRANS.TBL
dd f2 install.sh mbr_backup mm sdb1 sdb3 src
这个文件就是一张黑色的图片,就是选择菜单的黑色背景。
画图打开一个图片
重新设置图片像素为640×480保存到桌面
然后将这个图片传到centos6中
yum install ImageMgick 在ImageMgick中有一个convert
convert -resize 640×480 -colors 14 793-160324161216.jpg win.xpm
gzip win.xpm
mv win.xpm.gz /boot/grub
[root@centos6 ~]#vim /boot/grub/grub.conf
# grub.conf generated by anaconda
# i
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/win.xpm.gz
reboot
图片更换完成
使破解口令难度加大:
在/boot/grub/grub.conf中加入新的hang
password wang
password –md5 $1$qgyKr/$DclcUQW7FKY1bq6uvDMA01
password –encrypted $6$Iq55.nVdKlhiv4J/$Ou5CTonH3wrPaTJoA4SPrBiip5LOjShgytg05sdDMOYQy1wHasVuWw9kdmaS.1kBOCtyD6Ng7LlIKxh7f3Y0I1
生成加密口令的命令:grub-md5-crypt
[root@centos6 ~]#grub-md5-crypt
Password:
Retype password:
$1$qgyKr/$DclcUQW7FKY1bq6uvDMA01
生成加密口令的命令:grub-crypt
[root@centos6 ~]#grub-crypt
Password:
Retype password:
$6$Iq55.nVdKlhiv4J/$Ou5CTonH3wrPaTJoA4SPrBiip5LOjShgytg05sdDMOYQy1wHasVuWw9kdmaS.1kBOCtyD6Ng7LlIKxh7f3Y0I1
数组
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
索引:编号从0开始,属于数值索引
注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,
bash4.0版本之后开始支持
bash的数组支持稀疏格式(索引不连续)连续数组中缺少了某些元数就是稀疏格式
声明数组:
declare -a ARRAY_NAME
declare -A ARRAY_NAME: 关联数组 关联数组必须先声明后使用。
注意:两者不可相互转换
[root@centos6 ~]#bash –version 查看bash的版本
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
数组赋值
数组元素的赋值
(1) 一次只赋值一个元素
ARRAY_NAME[INDEX]=VALUE
weekdays[0]=”Sunday”
weekdays[4]=”Thursday”
(2) 一次赋值全部元素
ARRAY_NAME=(“VAL1” “VAL2” “VAL3” …)
(3) 只赋值特定元素
ARRAY_NAME=([0]=”VAL1″ [3]=”VAL2″ …)
(4) 交互式数组值对赋值
read -a ARRAY
显示所有数组:declare -a
[root@centos6 ~]#title[0]=ceo
[root@centos6 ~]#title[1]=cto
[root@centos6 ~]#title[2]=cfo
引用数组
引用数组元素:
${ARRAY_NAME[INDEX]}
注意:省略[INDEX]表示引用下标为0的元素
引用数组所有元素:
${ARRAY_NAME[*]}
${ARRAY_NAME[@]}
数组的长度(数组中元素的个数):
${#ARRAY_NAME[*]}
${#ARRAY_NAME[@]}
删除数组中的某元素:导致稀疏格式
unset ARRAY[INDEX]
删除整个数组:
unset ARRAY
[root@centos6 ~]#name=(wang lele liu) 一次赋多个数组值
[root@centos6 ~]#echo ${name[0]} 引用数组
wang
[root@centos6 ~]#echo ${name[*]} 显示所有元数
wang lele liu
[root@centos6 ~]#echo $name 只能显示第一个数组
wang
[root@centos6 ~]#echo ${name} 默认省略[0]
wang
[root@centos6 ~]#echo $name[1] 显示错误
wang[1]
[root@centos6 ~]#num=(`echo {1..10}`)
[root@centos6 ~]#echo ${num[*]}
1 2 3 4 5 6 7 8 9 10
[root@centos6 ~]#filename=(`ls /root/*.sh`)
[root@centos6 ~]#echo ${filename[0]}
/root/df.sh
[root@centos6 ~]#echo ${filename[1]}
/root/morejobs.sh
[root@centos6 ~]#echo ${filename[*]}
/root/df.sh /root/morejobs.sh /root/wang.sh
[root@centos6 ~]#num=(`seq 10`)
[root@centos6 ~]#echo ${num[*]}
1 2 3 4 5 6 7 8 9 10
[root@centos6 ~]#filename=(/boot/*)
[root@centos6 ~]#echo ${filename[0]}
/boot/config-2.6.32-696.el6.x86_64
[root@centos6 ~]#echo ${filename[1]}
/boot/efi
[root@centos6 ~]#echo ${filename[*]}
/boot/config-2.6.32-696.el6.x86_64 /boot/efi /boot/grub /boot/initramfs-2.6.32-696.el6.x86_64.img /boot/lost+found /boot/symvers-2.6.32-696.el6.x86_64.gz /boot/System.map-2.6.32-696.el6.x86_64 /boot/vmlinuz-2.6.32-696.el6.x86_64
[root@centos6 ~]#filename=(f{1,2,3}.{log,txt})
[root@centos6 ~]#echo ${filename[*]}
f1.log f1.txt f2.log f2.txt f3.log f3.txt
[root@centos6 ~]#name=([0]=wang [2]=zhang) 稀疏格式
[root@centos6 ~]#echo ${name[1]}
[root@centos6 ~]#echo ${name[0]}
wang
[root@centos6 ~]#echo ${name[2]}
zhang
[root@centos6 ~]#echo ${name[*]}
wang zhang
[root@centos6 ~]#read -a title 交互式为数组赋值
boss ceo cto beiguoxia
[root@centos6 ~]#echo ${title[0]}
boss
[root@centos6 ~]#echo ${title[1]}
ceo
[root@centos6 ~]#echo ${title[2]}
cto
[root@centos6 ~]#echo ${title[3]}
beiguoxia
[root@centos6 ~]#echo ${title[*]}
boss ceo cto beiguoxia
关联数组必须先声明要不然会出现下列错误
[root@centos6 ~]#title[ceo]=mage
[root@centos6 ~]#title[coo]=zhang
[root@centos6 ~]#echo ${title[ceo]}
zhang
[root@centos6 ~]#echo ${title[coo]}
zhang
[root@centos6 ~]#declare -A title
[root@centos6 ~]#title[ceo]=mage
[root@centos6 ~]#title[coo]=zhang
[root@centos6 ~]#echo ${title[ceo]}
mage
[root@centos6 ~]#echo ${title[coo]}
zhang
查看数组中有多少个元数
[root@centos6 ~]#echo ${#title[*]}
2
[root@centos6 ~]#echo ${#name[*]}
2
[root@centos6 ~]#echo ${#num[*]}
10
如果数组是连续的那么这个数组的最后一个下标是这个数组的个数减一
如果要加入一个新的元数那么这个元数的下标就是这个数组之前的个数
[root@centos6 ~]#echo ${name[*]}
a b c
[root@centos6 ~]#echo ${#name[*]}
3
[root@centos6 ~]#name[${#name[*]}]=x
[root@centos6 ~]#echo ${#name[*]}
4
[root@centos6 ~]#echo ${name[*]}
a b c x
[root@CENTOS7 ~]#vim max-min.sh 比较10个随机生成数的大小
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-11
#FileName: max-min.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -a rand
for ((i=0;i<10;i++));do
rand[$i]=$RANDOM
if [ “$i” -eq 0 ];then
max=${rand[$i]}
min=$max
else
[ $max -lt ${rand[$i]} ] && { max=${rand[$i]} ;continue; }
[ $min -gt ${rand[$i]} ]&& min=${rand[$i]}
fi
done
echo $max
echo $min
echo ${rand[*]}
“max-min.sh” 25L, 614C written
[root@CENTOS7 ~]#./max-min.sh
28419
8710
24405 22016 16541 8710 28419 21459 24498 17134 17641 20700
生成10个随机数保存于数组中,并找出其最大值和最小值
#!/bin/bash
declare -i min max
declare -a nums
for ((i=0;i<10;i++));do
nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[$i]} && max=${nums[$i]}&& continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]}
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo “All numbers are ${nums[*]}”
echo Max is $max
echo Min is $min
数组数据处理
引用数组中的元素:
数组切片:${ARRAY[@]:offset:number}
offset: 要跳过的元素个数
number: 要取出的元素个数
取偏移量之后的所有元素
${ARRAY[@]:offset}
向数组中追加元素:
ARRAY[${#ARRAY[*]}]=value
关联数组:
declare -A ARRAY_NAME
ARRAY_NAME=([idx_name1]=’val1′ [idx_name2]=’val2‘…)
注意:关联数组必须先声明再调用
取分区利用率
[root@CENTOS7 ~]#vim fenqu.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-11
#FileName: fenqu.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -A fenqu
df | grep “/dev/sd” > f1
while read i ; do
a=`echo $i | cut -d ” ” -f 1`
b=`echo $i | sed -r ‘s/.* ([0-9]+)%.*/\1/’`
fenqu[$a]=$b
done < f1
echo ${fenqu[*]}
~
~
~
“fenqu.sh” 19L, 521C written
[root@CENTOS7 ~]#./fenqu.sh
16 1 8
示例
编写脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;统
计出其下标为偶数的文件中的行数之和
#!/bin/bash
#
declare -a files
files=(/var/log/*.log)
declare -i lines=0
for i in $(seq 0 $[${#files[*]}-1]); do
if [ $[$i%2] -eq 0 ];then
let lines+=$(wc -l ${files[$i]} | cut -d’ ‘ -f1)
fi
done
echo “Lines: $lines.”
[root@CENTOS7 ~]#vim shuzu.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2018-05-12
#FileName: shuzu.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -a num
sum=0
num=(/var/log/*.log)
for i in `seq 0 $[${#num[*]}-1]`;do
if [ $[$i%2] -eq 0 ];then
let sum=sum+`wc -l ${num[$i]} | cut -d ” ” -f1`
fi
done
echo $sum
~
~
“shuzu.sh” 20L, 517C written
[root@CENTOS7 ~]#bash shuzu.sh
1566
冒泡算法:a b c d e 比较大小
转置矩阵: 123 147
num[00]=1
num[01]=2 456 258
num[02]=3 789 369
字符串切片
${#var}:返回字符串变量var的长度
${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字
符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个
字符)的字符开始,长度为number的部分
${var: -length}:取字符串的最右侧几个字符
注意:冒号后必须有一空白字符
${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字
符之前的内容
${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最
右侧offset个字符之间的内容
注意:-length前空格
[root@CENTOS7 ~]#a=`echo {a..z} | tr -d ” “`
[root@CENTOS7 ~]#echo $a
abcdefghijklmnopqrstuvwxyz
[root@CENTOS7 ~]#echo ${#a}
26
[root@CENTOS7 ~]#echo ${a:4} :10跳过10个不包括第10个字符,
efghijklmnopqrstuvwxyz
[root@CENTOS7 ~]#echo ${a:4:2}
ef
[root@CENTOS7 ~]#echo ${a: -4} 在:和-10之间有空格
wxyz
[root@CENTOS7 ~]#echo ${a:4: -4}
efghijklmnopqrstuv
[root@CENTOS7 ~]#echo ${a: -4:1}
w
[root@CENTOS7 ~]#echo ${a: -4:2}
wx
[root@CENTOS7 ~]#echo ${a: -4:-1} 在centos6上不支持
wxy
字符串处理
基于模式取子串
${var#*word}:其中word可以是指定的任意字符
功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删
除字符串开头至第一次出现word字符之间的所有字符
${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后
一次由word指定的字符之间的所有内容
示例:
file=“var/log/messages”
${file#*/}: log/messages
${file##*/}: messages
[root@CENTOS7 ~]#line=`head -n1 /etc/passwd`
[root@CENTOS7 ~]#echo $line
root:x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line#*:}
x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line##*:}
/bin/bash
字符串处理
${var%word*}:其中word可以是指定的任意字符
功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删
除字符串最后一个字符向左至第一次出现word字符之间的所有字符
file=”/var/log/messages”
${file%/*}: /var/log
${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现
word字符之间的所有字符;
示例:
url=http://www.magedu.com:80
${url##*:} 80
${url%%:*} http
[root@CENTOS7 ~]#echo ${line%:*}
root:x:0:0:root:/root
[root@CENTOS7 ~]#echo ${line%%:*}
root
[root@CENTOS7 ~]#disk=”/dev/sda2 52403200 4088408 48314792 8% /”
[root@CENTOS7 ~]#echo $disk
/dev/sda2 52403200 4088408 48314792 8% /
[root@CENTOS7 ~]#echo ${disk%% *}
/dev/sda2
[root@CENTOS7 ~]#iptables -vnL 查看防火墙是否关闭
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
[root@centos6 ~]#curl 172.20.109.255 访问centos7上开启的httpd服务
[root@CENTOS7 ~]#cat /var/log/httpd/access_log > f1
[root@CENTOS7 ~]#while read i ; do echo ${i%% *}; done < f1
172.20.102.175
172.20.68.110
172.20.68.110
字符串处理
查找替换
${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹
配到的字符串,以substr替换之
${var//pattern/substr}: 查找var所表示的字符串中,所有能被pattern所匹
配到的字符串,以substr替换之
${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹
配到的字符串,以substr替换之
${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹
配到的字符串,以substr替换之
[root@CENTOS7 ~]#echo ${line}
root:x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line/:/;}
root;x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line//:/;}
root;x;0;0;root;/root;/bin/bash
[root@CENTOS7 ~]#echo ${line/#root/admin} 以root开头的
admin:x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line/%bash/csh} 以bash结尾的
root:x:0:0:root:/root:/bin/csh
字符串处理
查找并删除
${var/pattern}:删除var所表示的字符串中第一次被pattern所匹配到的字符串
${var//pattern}:删除var所表示的字符串中所有被pattern所匹配到的字符串
${var/#pattern}:删除var所表示的字符串中所有以pattern为行首所匹配到的
字符串
${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的
字符串
字符大小写转换
${var^^}:把var中的所有小写字母转换为大写
${var,,}:把var中的所有大写字母转换为小写
[root@CENTOS7 ~]#echo ${line/root/}
:x:0:0:root:/root:/bin/bash
[root@CENTOS7 ~]#echo ${line//root/}
:x:0:0::/:/bin/bash
[root@CENTOS7 ~]#echo $a
root:x:0:0:root:/root:/bin/bash/root
[root@CENTOS7 ~]#echo ${a/#root}
:x:0:0:root:/root:/bin/bash/root
[root@CENTOS7 ~]#echo ${a/%root}
root:x:0:0:root:/root:/bin/bash/
[root@CENTOS7 ~]#echo ${a^^}
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH/ROOT
[root@CENTOS7 ~]#echo $b
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH/ROOT
[root@CENTOS7 ~]#echo ${b,,}
root:x:0:0:root:/root:/bin/bash/root
高级变量用法-有类型变量
Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令
用于指定变量的类型,两个命令是等价的
declare [选项] 变量名
-r 声明或显示只读变量
-i 将变量定义为整型数
-a 将变量定义为数组
-A 将变量定义为关联数组
-f 显示已定义的所有函数名及其内容
-F 仅显示已定义的所有函数名
-x 声明或显示环境变量和函数
-l 声明变量为小写字母 declare –l var=UPPER
-u 声明变量为大写字母 declare –u var=lower
[root@CENTOS7 ~]#declare -xf 查看全局函数
[root@CENTOS7 ~]#a(){ echo wang; }
[root@CENTOS7 ~]#a
wang
[root@CENTOS7 ~]#export -f a
[root@CENTOS7 ~]#declare -f -x
a ()
{
echo wang
}
declare -fx a
eval命令
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于
那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描
示例:
[root@server ~]# CMD=whoami
[root@server ~]# echo $CMD
whoami
[root@server ~]# eval $CMD
root
[root@server ~]# n=10
[root@server ~]# echo {0..$n}
{0..10}
[root@server ~]# eval echo {0..$n}
0 1 2 3 4 5 6 7 8 9 10
[root@CENTOS7 ~]#n=10
[root@CENTOS7 ~]#echo {1..$n}
{1..10}
[root@CENTOS7 ~]#eval echo {1..$n}
1 2 3 4 5 6 7 8 9 10
间接变量引用
如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值
就称为间接变量引用
variable1的值是variable2,而variable2又是变量名,variable2的值为value,
间接变量引用是指通过variable1获得变量值value的行为
variable1=variable2
variable2=value
[root@CENTOS7 ~]#cmd1=cmd2
[root@CENTOS7 ~]#echo $cmd1
cmd2
[root@CENTOS7 ~]#cmd2=wang
[root@CENTOS7 ~]#echo $cmd2
wang
[root@CENTOS7 ~]#eval echo \$$cmd1
wang
[root@CENTOS7 ~]#echo ${!cmd1}
wang
间接变量引用
bash Shell提供了两种格式实现间接变量引用
eval tempvar=\$$variable1
tempvar=${!variable1}
示例:
[root@server ~]# N=NAME
[root@server ~]# NAME=wangxiaochun
[root@server ~]# N1=${!N}
[root@server ~]# echo $N1
wangxiaochun
[root@server ~]# eval N2=\$$N
[root@server ~]# echo $N2
wangxiaochun
创建临时文件
mktemp命令:创建并显示临时文件,可避免冲突
mktemp [OPTION]… [TEMPLATE]
TEMPLATE: filenameXXX
X至少要出现三个
OPTION:
-d: 创建临时目录
-p DIR或–tmpdir=DIR:指明临时文件所存放目录位置
示例:
mktemp /tmp/testXXX
tmpdir=`mktemp –d /tmp/testdirXXX`
mktemp –tmpdir=/testdir testXXXXXX
[root@CENTOS7 ~]#mktemp /data/123XXX
/data/123onX
[root@CENTOS7 ~]#mktemp /data/123XXX
/data/1230T1
[root@CENTOS7 ~]#mktemp /data/123XXX
/data/123iS6
[root@CENTOS7 ~]#mktemp -d /data/nihaoXXX
/data/nihaozDc
[root@CENTOS7 ~]#a=/data
[root@CENTOS7 ~]#mktemp $a/123XXX
/data/1235J6
安装复制文件
install命令:
install [OPTION]… [-T] SOURCE DEST 单文件
install [OPTION]… SOURCE… DIRECTORY
install [OPTION]… -t DIRECTORY SOURCE…
install [OPTION]… -d DIRECTORY…创建空目录
选项:
-m MODE,默认755
-o OWNER
-g GROUP
示例:
install -m 700 -o wang -g admins srcfile desfile
install –m 770 –d /testdir/installdir
[root@CENTOS7 ~]#install -m 770 -o wang -g root /etc/shadow /data/password.txt
[root@CENTOS7 ~]#ll /data/password.txt
-rwxrwx— 1 wang root 1932 May 12 11:16 /data/password.txt
[root@CENTOS7 ~]#install -d /data/123 -m 000
[root@CENTOS7 ~]#ll -d /data/123
d——— 2 root root 6 May 12 11:31 /data/123
[root@CENTOS7 ~]#mkdir /data/321 -m 000
[root@CENTOS7 ~]#ll -d /data/321
d——— 2 root root 6 May 12 11:31 /data/321
expect介绍
expect 是由Don Libes基于Tcl( Tool Command Language )语言开发的,
主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互
过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需
要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率
expect命令
expect 语法:
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
选项
-c:从命令行执行expect脚本,默认expect是交互地执行的
示例:expect -c ‘expect “\n” {send “pressed enter\n”}
-d:可以输出输出调试信息
示例:expect -d ssh.exp
expect中相关命令
spawn:启动新的进程
send:用于向进程发送字符串
expect:从进程接收字符串
interact:允许用户交互
exp_continue 匹配多个字符串在执行动作后加此命令
[root@CENTOS7 ~]#expect
expect1.3> expect “hi” {send “you said hi\n”}
hi
you said hi
expect
expect最常用的语法(tcl语言:模式-动作)
单一分支模式语法:
expect “hi” {send “You said hi\n”}
匹配到hi后,会输出“you said hi”,并换行
多分支模式语法:
expect “hi” { send “You said hi\n” } \
“hehe” { send “Hehe yourself\n” } \
“bye” { send “Good bye\n” }
匹配hi,hello,bye任意字符串时,执行相应输出。等同如下:
expect {
“hi” { send “You said hi\n”}
“hehe” { send “Hehe yourself\n”}
“bye” { send “Good bye\n”}
}
[root@CENTOS7 ~]#expect
expect1.1> expect “hi” {send “you said hi\n”}
hi
you said hi
expect1.2> expect “hi” {send “you said hi\n”} \
+> “hehe” {send “hehe yourself\n”} \
+> “bey” {send “good bye\n”}
hey
bey
good bye
[root@CENTOS7 ~]#expect
expect1.1> expect {
+> “hi” {send “you said hi\n”}
+> “hehe” {send “hehe nimei\n”}
+> “bye” {send “good bye\n”}
+> }
hehe
hehe nimei
示例
#!/usr/bin/expect
spawn scp /etc/fstab 192.168.8.100:/app
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “magedu\n” }
}
expect eof
[root@CENTOS7 ~]#vim scp.exp
#!/usr/bin/expect
spawn scp /etc/fstab 192.168.30.102:/data
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “magedu\n” }
}
expect eof
spawn scp /etc/fstab 192.168.30.102:/data
The authenticity of host ‘192.168.30.102 (192.168.30.102)’ can’t be established.
RSA key fingerprint is SHA256:PRXpd893BtvDDcy5yeFh/MVuBjM7LPWwz0JH9Zs+Ia4.
RSA key fingerprint is MD5:08:44:ca:54:1c:a9:20:64:42:40:59:cc:98:be:bd:bc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘192.168.30.102’ (RSA) to the list of known hosts.
root@192.168.30.102’s password:
fstab 100% 595 795.0KB/s 00:00
如果用ssh连接别的主机半天连接不上则可有可能是
[root@CENTOS7 ~]#vim /etc/ssh/sshd_config
SSAPIAuthentication yes 将这项修改成no 79行
#UseDNS no 修改成 UseDNS no 115行
[root@CENTOS7 ~]#systemctl restart sshd 从新生效一下
自动ssh连接登录
[root@CENTOS7 ~]#vim ssh2.exp
#!/usr/bin/expect
spawn ssh 192.168.30.102
expect {
“yes/no” { send “yes\n” exp_continue }
“password” { send “magedu\n” }
}
interact 这个地方一定要写interact如果写成expect eof 则无法继续后续的命令
示例
#!/usr/bin/expect
spawn ssh 192.168.8.100
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “magedu\n” }
}
interact
#expect eof
示例:变量
#!/usr/bin/expect
set ip 192.168.8.100 在expect中变量赋值需要set
set user root
set password magedu
set timeout 10
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
interact
示例:位置参数
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
interact
#./ssh3.exp 192.168.8.100 root magedu
示例:执行多个命令
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set timeout 10
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
expect “]#” { send “useradd haha\n” }
expect “]#” { send “echo magedu |passwd –stdin haha\n” }
send “exit\n”
expect eof
#./ssh4.exp 192.168.8.100 root magedu
示例:shell脚本调用expect
#!/bin/bash
ip=$1
user=$2
password=$3
expect <<EOF
set timeout 10
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
expect “]#” { send “useradd hehe\n” }
expect “]#” { send “echo magedu |passwd –stdin hehe\n” }
expect “]#” { send “exit\n” }
expect eof
EOF
#./ssh5.sh 192.168.8.100 root magedu
[root@CENTOS7 ~]#vim scp2.exp
#!/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]
spawn scp /etc/passwd $user@$ip:/data
expect {
“yes/no” { send “yes\n”; exp_continue }
“password” { send “$passwd\n” }
}
expect eof
[root@CENTOS7 ~]#vim scp1.sh
#!/bin/bash
user=root
passwd=magedu
while read ip ;do
/root/scp2.exp $ip $user $passwd
done < f121
centos6 启动流程
1 post 硬件环境
2 mbr 446 grub stage1
3 grub stage1.5 加载/boot 分区文件系统
4 grub stage2 /boot/grub/grub.conf
5 vmlinuz 加载/ /boot/initramfs.xxx.img
6 /sbin/init /etc/inittab id:3:
7 rc.sysinit
8 /etc/rc3.d/S,Kxxx –> /etc/init.d/xxx
chkconfig –level N service on|off
9 /etc/rc.local
10 login
删除/boot/下的所有文件,恢复过程
第一种方法
1.进入救援模式
2.chroot /mnt/sysimage
3.mount /dev/sr0 /mnt
4.cp /mnt/isolinux/vmlinuz /boot/vmlinuz-`uname -r`
5.mkinitrd initramfs-`uname -r`.x86_64.img `uname -r`
6.grub-install /dev/sda
7.vi grub.conf
default=0
timeout=5
titel wanglinux
root (hd0,0)
kernel /vmlinuz-`uname -r` root=/dev/sda2 rhgb quiet
initrd /initramfs-`uname -r`x86_64
第二种方法
1.进入救援模式
2.mount /mnt/cdroom
3.rpm -ivh /mnt/cdroom/Packages/kernel-2.6.32-696.e16.x86_64.rpm –root=/mnt/sysimage/ –forc
4.chroot /mnt/sysimage
5.grub-install
6.vim /boot/grub/grub.conf
default=0
timeout=5
titel linux wang
kernel /用:r!ls /boot/vmlinuz按Tab补全 root=/dev/sda2 可以在此加selinux=0,禁用selinux
initrd /用:r!ls /boot/initramfs按Tab补全
如果/boot不是一个独立分区
那么
kernel / kernel /boot/
initrd /,这两行不能这么写,要写成initrd /boot/
删除/etc/fstab,同时清空/boot/下的所有文件。如何修复
1.进入救援模式
2.fdisk -l查看分区
3.mkdir /mnt/rootfs
4.mount /dev/sda1 /mnt/rootfs 从/dev/sda1开始尝试找到/
5.ls
umount /mnt/rootfs
6.mount /dev/sda2 /mnt/rootfs
看一下/分区的文件系统blkid
7.vi /mnt/rootfs/etc/fstab
/dev/sda2 / ext4 defaults 0 0
/dev/sda1 /boot ext4 defualts 0 0
/dev/sda5 swap swap defaults 0 0
/dev/sda3 /data ext4 defaults 0 0
exit
reboot
重新进入救援模式
1.进入救援模式
2.重复上述修复/boot操作
磁盘是逻辑卷如何恢复
如果是逻辑卷进入救援模式后要先启动逻辑卷
lvchange -ay
就可以挂载了
如果破坏init文件如何修复
1.进入救援模式,开启网络服务并配置地址
2.在都是centos6上的机器上远程拷贝一份
chroot /mnt/sysimage 切/
3.scp 192.168.30.105(能开启的centos6的ip地址):/sbin/init /sbin/
exit
reboot
第二种方法
1.进入救援模式
chroot /mnt/sysimage
2.rpm2cpio /misc/cd/Packages/upstart-0.65-el6.x86_64.rpm | cpio -idv ./sbininit
cp ./sbin/init /sbin/
自制一个小linux
自制linux系统
分区并创建文件系统
fdisk /dev/sdb
分两个必要的分区
/dev/sdb1对应/boot /dev/sdb2对应根 /
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
挂载boot
mkdir /mnt/boot 子目录必须为boot
mount /dev/sdb1 /mnt/boot
安装grub
grub-install –root-directory=/mnt /dev/sdb
自制一个小linux
1.
添加一块新的硬盘20G(移动硬盘,U盘都可以)dev/sdb
2.
fdisk /dev/sdb分两个主分区
3.
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
4.
mkdir /mnt/boot 子目录必须是boot
mkdir /mnt/rootfs
mount /dev/sdb1 /mnt/boot
grub-install –root-directory=/mnt /dev/sdb –root-directory=/ 这个命令默认是boot的父文件夹
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/vmlinuz
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot/initramfs.img
cat > /mnt/boot/grub/grub.conf
default=0
timeout=5
title linux wang
blkid
kernel /vmlinuz root=/dev/sda2(root=UUID=) init=/bin/bash selinux=0,自动拥有IP地址,创建一个软连接让/sbin/init→一个bash脚本,脚本中写着/bin/bash,insmod /lib/e1000.ko ifconfig etho 192.168.30.16/24
initrd /initramfs.img
mount /dev/sdb2 /mnt/rootfs
运行 cmd_copy.sh
ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid
mkdir /mnt/rootfs/{dev,etc,proc,sys,usr,bin,sbin,var,lib,boot,mnt,home,root,emp}
cp /lib/modules/3.10.0-693.el7.x86_64/kernel/drivers/net/ethernet/intel/e1000/e1000.ko.xz /mnt/rootfs/lib/
sync
sync
sync
拆掉硬盘(移动硬盘,U盘)
自制linux系统
分区并创建文件系统
fdisk /dev/sdb
分两个必要的分区
/dev/sdb1对应/boot /dev/sdb2对应根 /
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
挂载boot
mkdir /mnt/boot 子目录必须为boot
mount /dev/sdb1 /mnt/boot
安装grub
grub-install –root-directory=/mnt /dev/sdb
自制linux系统
恢复内核和initramfs文件
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot
建立grub.conf
vim /mnt/boot/grub.conf
title wanglinux
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2 selinux=0
init=/bin/bash
initrd /initramfs-2.6.32-642.el6.x86_64.img
chroot /mnt/sysroot
自制linux系统
创建一级目录
mkdir /mnt/sysroot
mount /dev/sdb2 /mnt/sysroot
mkdir –pv
/mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,
dev,mnt,media}
复制bash和相关库文件
复制相关命令及相关库文件
如:ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid等
救援环境
在根文件系统无法使用时需要,如/bin/mount删除
对系统没有特殊要求
从光盘引导(boot.iso或者安装光盘#1)
从USB盘(由boot.iso制作)引导
系统配置文件丢失修复
系统在引导期间,很重要的一个过程就是init进程读取其配置文件/etc/inittab,
启动系统基本服务程序及默认运行级别的服务程序完成系统引导,如果
/etc/inittab误删除或修改错误,Linux将无法正常启动。此时,只有通过救援模
式才可以解决此类问题。
有备份文件的回复方法
没有备份文件的恢复办法
系统配置文件丢失修复
有备份文件的恢复办法:
进入救援模式,执行chroot命令后,如果有此文件的备份(强烈建议系统中的重要
数据目录,如/etc、/boot等要进行备份),直接将备份文件拷贝回去,退出重启即
可。如果是配置文件修改错误,如比较典型的/boot/grub/grub.conf及
/etc/passwd的文件修改错误,也可以直接修正恢复。假设有备份文件
/etc/inittab.bak,则在救援模式下执行:
chroot /mnt/sysimage
cp /etc/inittab.bak /etc/inittab
系统配置文件丢失修复
没有备份文件的恢复办法
如果一些配置文件丢失或软件误删除,且无备份,可以通过重新安装软件包来恢复,
首先查找到/etc/inittab属于哪一个RPM包
chroot /mnt/sysimage
rpm -qf /etc/inittab
initscripts-9.03.49-1.el6.centos.x86_64
exit 退出chroot模式
挂载存放RPM包的安装光盘(在救援模式下,光盘通常挂载在/mnt/source目录下)
系统配置文件丢失修复
mount /dev/sr0 /mnt/source
CentOS6系统的RPM包存放在光盘Package目录下,要修复的硬盘系统的根目
录在/mnt/sysimage下,需要使用–root选项指定其位置。覆盖安装/etc/inittab
文件所在的RPM包:
rpm -ivh –replacepkgs | force /mnt/source/Packages/
initscripts-9.03.49-1.el6.centos.x86_64.rpm
其中的rpm命令选项“–replacepkgs”表示覆盖安装,执行完成后,即已经恢复
了此文件
系统配置文件丢失修复
如果想只提取RPM包中的/etc/inittab文件进行恢复,可以在进入救援模式后,执
行命令:
rpm2cpio /mnt/source/Packages/initscripts-9.03.49-
1.el6.centos.x86_64.rpm| cpio -idv ./etc/inittab
cp etc/inittab /mnt/sysimage/etc
注意此命令执行时不能将文件直接恢复至/etc目录,只能提取到当前目录下,且恢
复的文件名称所在路径要写完整的路径。提取文件成功后,将其复制到根分区所在
的/mnt/sysimage目录下相应位置即可
/proc目录
/proc目录:
内核把自己内部状态信息及统计信息,以及可配置参数通
过proc伪文件系统加以输出
参数:只读:输出信息
可写:可接受用户指定“新值”来实现对内核某功
能或特性的配置
/proc/sys
(1) sysctl命令用于查看或设定此目录中诸多参数
sysctl -w path.to.parameter=VALUE
sysctl -w kernel.hostname=mail.magedu.com
(2) echo命令通过重定向方式也可以修改大多数参数的值
echo “VALUE” > /proc/sys/path/to/parameter
echo “websrv” > /proc/sys/kernel/hostname
[root@CENTOS7 ~]#cat /proc/sys/net/ipv4/ip_forward
0
[root@CENTOS7 ~]#cat /proc/sys/net/ipv4/ip_default_ttl
64
禁ping
[root@centos6 ~]#cat /proc/sys/net/ipv4/icmp_echo_ignore_all
0
这些文件都可以由/etc/sysctl.conf文件来配置
[root@centos6 ~]#vim /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
#
# Use ‘/sbin/sysctl -a’ to list all possible parameters.
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
[root@centos6 ~]#cat /proc/sys/net/ipv4/ip_forward 虽然修改了文件的ip_farword 的值,但是文件并没有生效,
0
让文件生效的命令是sysctl -p 让系统重读这个文件
[root@centos6 ~]#sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
[root@centos6 ~]#cat /proc/sys/net/ipv4/ip_forward
1
[root@centos6 ~]#cat /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
#
# Use ‘/sbin/sysctl -a’ to list all possible parameters.
# Controls IP packet forwarding
net.ipv4.ip_forward = 1 机器是否能当路由使用
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1
# Controls the default maxmimum size of a mesage queue
kernel.msgmnb = 65536
# Controls the maximum size of a message, in bytes
kernel.msgmax = 65536
# Controls the maximum shared segment size, in bytes 共享内存的断大小,60多G
kernel.shmmax = 68719476736 将来使用oracle数据库希望使用更大的内存,
要将这个数调大
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296
查看所有内存参数
sysctl -a
[root@centos6 ~]#sysctl -a
net.ipv4.tcp_syn_retries = 5 尝试连接5次
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_fin_timeout = 60 分手超时时间60秒
net.ipv4.tcp_syncookies = 1 cookies可以存放一些用户信息
net.ipv4.tcp_max_tw_buckets = 131072 timeout能够保留这个状态的个数
net.ipv4.tcp_max_syn_backlog = 1024 最多等待队列
net.ipv4.tcp_max_orphans = 131072 最大孤儿连接数
net.ipv4.ip_local_port_range = 32768 60999 客户端端口个数(反向代理服务器)
[root@centos6 ~]#sysctl -a | grep icmp
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.ipv4.icmp_echo_ignore_all = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.icmp_errors_use_inbound_ifaddr = 0
net.ipv4.icmp_ratelimit = 1000
net.ipv4.icmp_ratemask = 6168
net.ipv6.icmp.ratelimit = 1000
[root@centos6 ~]#vim /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
#
# Use ‘/sbin/sysctl -a’ to list all possible parameters.
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_all = 1 在这加上行禁ping
在文件生效之前可以ping通
sysctl -p
则无法ping通
这是删除/etc/sysctl.conf这个文件中加入的net.ipv4.icmp_echo_ignore_all = 1还是无法ping通
sysctl -p 之后也无法ping通
因为sysctl -p是重读次文件,只有文件中与内存中不相符的文件才修改内存,已将删除了这个文件,那么内存中是什么就是什么不会修改
[root@centos6 ~]#sysctl -w net.ipv4.icmp_echo_ignore_all=0 这个也是修改内存,但是存不住。
net.ipv4.icmp_echo_ignore_all = 0
sysctl命令
sysctl命令:
默认配置文件:/etc/sysctl.conf
(1) 设置某参数
sysctl -w parameter=VALUE
(2) 通过读取配置文件设置参数
sysctl -p [/path/to/conf_file]
(3) 查看所有生效参数
sysctl -a
常用的几个参数:
net.ipv4.ip_forward
net.ipv4.icmp_echo_ignore_all
vm.drop_caches
[root@centos6 ~]#time ls 查看命令所用时间
123 anaconda-ks.cfg install.log p2 src
2018 bin install.log.syslog Pictures Templates
20180417 Desktop morejobs.sh Public usr
20180417-+09:58:22 df.sh Music [root@centos6 Videos
20180417-09:58:32 Documents nohup.out samba-3.6.23-41.el6.x86_64.rpm vsftpd-3.0.2-22.el7.x86_64.rpm
793-160324161216.jpg Downloads p1 scp2.ecp wang.sh
real 0m0.002s
user 0m0.001s
sys 0m0.001s
[root@centos6 ~]#sysctl -w vm.drop_caches=1 清理缓存
/sys目录
/sys目录:
sysfs:为用户使用的伪文件系统,输出内核识别出的各硬件设备的相关属
性信息,也有内核对硬件特性的设定信息;有些参数是可以修改的,用于调整硬件
工作特性
udev通过此路径下输出的信息动态为各设备创建所需要设备文件,udev是
运行用户空间程序
专用工具:udevadmin, hotplug
udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在
/etc/udev/rules.d及/usr/lib/udev/rules.d目录下
内核编译
单内核体系设计、但充分借鉴了微内核设计体系的优点,为内核引入模块化机
制
内核组成部分:
kernel: 内核核心,一般为bzImage,通常在/boot目录下,名称为
vmlinuz-VERSION-RELEASE
kernel object: 内核对象,一般放置于
/lib/modules/VERSION-RELEASE/
[ ]: N
[M]: M
[*]: Y
辅助文件:ramdisk
initrd
initramfs
内核版本
运行中的内核:
uname命令:
uname – print system information
uname [OPTION]…
-n: 显示节点名称
-r: 显示VERSION-RELEASE
-a:显示所有信息
[root@centos6 ~]#uname -r 内核版本
2.6.32-696.el6.x86_64
内核模块命令
lsmod命令:
显示由核心已经装载的内核模块
显示的内容来自于: /proc/modules文件
modinfo命令:
显示模块的详细描述信息
modinfo [ -k kernel ] [ modulename|filename… ]
-n: 只显示模块文件路径
-p: 显示模块参数
-a: author
-d: description
-l: license
lsmod |grep xfs;modinfo xfs
编译内核和编译普通软件不同的地方就是你要告诉系统那些功能是启用的,那些功能
是不启用的,由于太多,因此我们编译内核的时候可以参照已经编译好的文件。
[root@centos6 ~]#cd /boot
[root@centos6 boot]#ls
vmlinuz-2.6.32-696.el6.x86_64 这个文件中存放着最基本得功能。
一些可用可不用的功能,没必要放到内核中,因此放到一个独立的文件中,需要使用就加载到内存中。
比如这个文件[root@CENTOS7 ~]#locate xfs.ko
/usr/lib/modules/3.10.0-693.el7.x86_64/kernel/fs/xfs/xfs.ko.xz
这些功能模块放在哪在下面这个文件中定义
config-2.6.32-696.el6.x86_64
[root@CENTOS7 ~]#less /boot/config-3.10.0-693.el7.x86_64
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 3.10.0-693.el7.x86_64 Kernel Configuration
#
CONFIG_64BIT=y y代表着打到内核里
CONFIG_X86_64=y
CONFIG_OPROFILE=m m表示放到单独文件中
CONFIG_GCOV_KERNEL is not set 不启用
[root@CENTOS7 ~]#wc -l /boot/config-3.10.0-693.el7.x86_64 这个文件的行数
5976 /boot/config-3.10.0-693.el7.x86_64
内核模块管理
modprobe命令:
装载或卸载内核模块
modprobe [ -C config-file ] [ modulename ] [ module parame-ters… ]
配置文件:/etc/modprobe.conf, /etc/modprobe.d/*.conf
modprobe [ -r ] modulename…
内核模块管理
depmod命令:
内核模块依赖关系文件及系统信息映射文件的生成工具
装载或卸载内核模块:
insmod命令:指定模块文件,不自动解决依赖模块
insmod [ filename ] [ module options… ]
insmod `modinfo –n exportfs`
lnsmod `modinfo –n xfs`
rmmod命令:卸载模块
rmmod [ modulename ]
rmmod xfs
rmmod exportfs
编译内核
前提:
(1) 准备好开发环境
(2) 获取目标主机上硬件设备的相关信息
(3) 获取目标主机系统功能的相关信息
例如:需要启用相应的文件系统
(4) 获取内核源代码包
www.kernel.org
开发环境准备
包组(CentOS 6):
Server Platform Development
Development Tools
目标主机硬件设备相关信息:
CPU:
cat /proc/cpuinfo
x86info -a
lscpu
硬件设备
PCI设备:
lspci
-v
-vv
lsusb
-v
-vv
lsblk 块设备
了解全部硬件设备信息
hal-device:CentOS6
内核编译安装系统
安装开发包组
下载源码文件
.config:准备文本配置文件
make menuconfig:配置内核选项
make [-j #]
make modules_install:安装模块
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件
编译安装内核示例
tar xf linux-3.10.67.tar.xz -C /usr/src
cd /usr/src
ln -sv linux-3.10.67 linux
cd /usr/src/linux
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig
make -j 2
make modules_install
make install
reboot
编译内核
(1) 配置内核选项
支持“更新”模式进行配置:make help
(a) make config:基于命令行以遍历的方式去配置内核中可配置的每个选
项
(b) make menuconfig:基于curses的文本窗口界面
(c) make gconfig:基于GTK (GNOME)环境窗口界面
(d) make xconfig:基于QT(KDE)环境的窗口界面
支持“全新配置”模式进行配置
(a) make defconfig:基于内核为目标平台提供的“默认”配置进行配置
(b) make allyesconfig: 所有选项均回答为“yes“
(c) make allnoconfig: 所有选项均回答为“no“
编译内核
(2) 编译
全编译:make [-j #]
编译内核的一部分功能:
(a) 只编译某子目录中的相关代码
cd /usr/src/linux
make dir/
(b) 只编译一个特定的模块
cd /usr/src/linux
make dir/file.ko
例如:只为e1000编译驱动:
make drivers/net/ethernet/intel/e1000/e1000.ko
编译内核
如何交叉编译内核:
编译的目标平台与当前平台不相同
make ARCH=arch_name
要获取特定目标平台的使用帮助
make ARCH=arch_name help
make ARCH=arm help
内核编译
在已经执行过编译操作的内核源码树做重新编译
需要事先清理操作:
make clean:清理大多数编译生成的文件,但会保留config文件等
make mrproper: 清理所有编译生成的文件、config及某些备份文件
make distclean:mrproper、patches以及编辑器备份文件
卸载内核
删除/lib/modules/目录下不需要的内核库文件
删除/usr/src/linux/目录下不需要的内核源码
删除/boot目录下启动的内核和内核映像文件
更改grub的配置文件,删除不需要的内核启动列表
编译安装linux内核文件
1.下载新的内核版本
传到linux中
sz
2.解压缩
tar xvf linux-4.16.8.tar.xz
3.cp /boot/config-3.10.0-693-e17.x86_64 .config
yum groupinstall “development tools”
yum install ncurses-decel
make menuconfig 选择想要启动的功能
general setup
Local version 回车 添加1.0wanglinux
file system
make -j 4
4.make modules_install:安装模块 生成模块文件,将模块文件拷贝到相应/lib/目录下.
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件
systemd
POST –> Boot Sequence –> Bootloader –> kernel + initramfs(initrd) —
> rootfs –> /sbin/init 第一个进程就找init是因为源码init文件夹中main.c中写的try_to_run_init_process(“/sbin/init”)
init: CentOS 5: SysV init 串行启动
CentOS 6: Upstart 部分并行
CentOS 7: Systemd 全部并行启动
Systemd:系统启动和服务器守护进程管理器,负责在系统启动或运行时,激
活系统资源,服务器进程和其它进程
Systemd新特性:
系统引导时实现服务并行启动
按需启动守护进程 代替超级守护(xinetd)管理进程,系统启动时只启动必要的进程,其他的只有在需要的时候才唤醒。
自动化的服务依赖关系管理 类似于yum,系统直接帮你启动有依赖的服务
同时采用socket式与D-Bus总线式激活服务
以前的版本httpd服务基于tcp服务而tcp 80想监听httpd服务就必须 socket file,以前是只有启动httpd服务才能生成socket文件。
在centos7上是独立开的,socket file平时打开监听80端口,一但有人访问,激活httpd服务。
系统状态快照
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/98374