@mrz1
2017-12-28T11:10:12.000000Z
字数 10024
阅读 810
笔记
检查磁盘空间利用率
max=5
df -h |grep "/dev/sd" |while read disk ;do
per=`echo $disk |sed -r 's/.* ([0-9]+)% .*/\1/'`
name=`echo $disk | cut -d' ' -f1`
[ "$per" -gt "$max" ] && echo $name 空间利用率超过了 ${max}%
done
PS1 命令提示符设置
PS2 多行重定向的提示符
PS3 select的提示符
select variable in list ;do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量REPLY 中
[root@centos6 ~]#vim select.sh
# Date: 2017-12-23
# FileName: select.sh
.......
# -------------------------------------------------------------
PS3="请输入查询编号查询价格:"
select menu in 宫爆鸡丁 拉面 鲍鱼 小龙虾 退出;do
case $REPLY in
1)
echo '宫爆鸡丁 ¥15'
;;
2)
echo '拉面 ¥15'
;;
3)
echo '鲍鱼 ¥30'
;;
4)
echo '小龙虾 ¥50'
;;
5)
break
;;
*)
echo '$REPLY 输入错误 '
echo '请重新输入'
;;
esac
done
运行结果:
[root@centos6 ~]#bash select.sh
1) 宫爆鸡丁 3) 鲍鱼 5) 退出
2) 拉面 4) 小龙虾
请输入查询编号查询价格:1
宫爆鸡丁 ¥15
请输入查询编号查询价格:2
拉面 ¥15
请输入查询编号查询价格:3
鲍鱼 ¥30
请输入查询编号查询价格:4
小龙虾 ¥50
请输入查询编号查询价格:5
HUP 1 终端断线
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
TERM 15 终止
KILL 9 强制终止
CONT 18 继续(与STOP相反, fg/bg命令)
STOP 19 暂停(同 Ctrl + Z)
#!/bin/bash
trap 'echo Don not break' INT
trap -p
for((i=0;i<=10;i++));do
sleep 1
echo $i
done
trap ''
int
trap -p
for((i=11;i<=20;i++));do
sleep 1
echo $i
done
trap '-'
int
trap -p
for((i=21;i<=30;i++));do
sleep 1
echo $i
done
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程
它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分
系统中定义函数位置cat /etc/init.d/functions
函数由两部分组成:函数名和函数体
help function
语法一:f_name(){...函数体...}
语法二:function f_name{...函数体...}
语法三:function f_name(){...函数体...}
示例:dir() {> ls-l> }
定义该函数后,若在$后面键入dir,其显示结果同ls-l的作用相同dir
该dir函数将一直保留到用户从系统退出,或执行了如下所示的unset命令:unsetdir
函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至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中删除函数。改动完毕后,再重新载入此文件
cat functions.main
#!/bin/bash
#functions.main
findit(){
if [ $# -lt 1 ] ; then
echo "Usage:findit file"
return 1
fi
find / -name $1 –print
}
函数文件已创建好后,要将它载入shell
定位函数文件并载入shell的格式:. filename 或source filename
注意:此即<点> <空格> <文件名>这里的文件名要带正确路径
示例:上例中的函数,可使用如下命令:. functions.main
使用set命令检查函数是否已载入。set命令将在shell中显示所有的载入函数
示例:
set findit=( )
{
if [ $# -lt 1 ]; then
echo "usage :findit file";
return 1
fi
find / -name $1 -print
}
要执行函数,简单地键入函数名即可
示例:
findit groups
/usr/bin/groups
/usr/local/backups/groups.bak
注意:如果函数中有局部变量,如果其名称同本地变量,使用局部变量
在函数中定义局部变量的方法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)!
示例:1
fact.sh
#!/bin/bash
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1
实例:1简写
fact () {
[ "$1" -eq 0 ] && echo 1 && return
echo $[`fact $[$1-1]`*$1]
}
read -p "阶乘算法,请输入数字:"n
fact $n
fork炸弹是一种恶意程序,它的内部是一个不断在fork进程的无限循环,实质是一个简单的递归程序。由于程序是递归的,如果没有任何限制,这会导致这个简单的程序迅速耗尽系统里面的所有资源
函数实现
:(){ :|:& };:
bomb() { bomb | bomb & }; bomb
脚本实现
cat Bomb.sh
#!/bin/bash
./$0|./$0&
osversion () {
echo `sed -r 's/.* ([0-9]+)\..*/\1/' /etc/centos-release`
}
osversion () {
num=`sed -r 's/.* ([0-9]+)\..*/\1/' /etc/centos-release`
if [ $num -eq 6 ];then
echo `ip addr|grep "scope global"|sed -r "s/.* (.*)\/.*/\1/"`
fi
if [ $num -eq 7 ];then
echo `ifconfig ens33 |grep netmask|tr -s " " :|cut -d: -f3`
fi
}
osversion
[root@centos6 ~]#. /etc/init.d/functions //直接调用系统脚本
[root@centos6 ~]#action "234567890"
234567890 [ OK ]
[root@centos6 ~]#action "234567890" false
234567890 [FAILED]
编写服务脚本/root/bin/testsrv.sh,完成如下要求
1. 脚本可接受参数:start, stop, restart, status
2. 如果参数非此四者之一,提示使用格式后报错退出
3. 如是start:则创建/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”考虑:如果事先已经启动过一次,该如何处理?
4. 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“停止完成”考虑:如果事先已然停止过了,该如何处理?
5. 如是restart,则先stop, 再start考虑:如果本来没有start,如何处理?
6. 如是status, 则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running...”如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped...”其中:SCRIPT_NAME为当前脚本名
7. 在所有模式下禁止启动该服务,可用chkconfig和service命令管理
参考:
#! /bin/bash
# chkconfig: 35 99 00 //3和5模式是on 99编号最后打开服务 00优先关闭服务
# description: this is a test service
case $1 in
start)
touch /app/testsrv
echo testsrv is starting
sleep 5 // 开机时为了能看到这个服务
;;
stop)
rm -f /app/testsrv
echo testsrv is stopped
;;
restart)
echo testsrv is stopped
echo testsrv is starting
;;
status)
[ -f /app/testsrv ] && echo testsrv is running || echo testsrv is stopped
;;
esac
chmod +x testsrc 添加执行权限
chkconfig --add testsrv 添加到服务列表中
chkconfig --list testsrv 查看所有模式对这个模式开还是关
编写脚本/root/bin/copycmd.sh
1. 提示用户输入一个可执行命令名称
2. 获取此命令所依赖到的所有库文件列表
3. 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下如:
/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd
提示:which ls 查询ls命令对应路径
4. 复制此命令依赖到的所有库文件至目标目录下的对应路径下:
如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
提示:ldd /bin/ls 命令依赖到的所有库文件
5. 每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit退出
yum install telnet-server 安装
vim /etc/xinet.d/telnet
disable=no 编写文件
或者 命令生成 chkconfig telnet on
误删除BOOT下文件和/ETC/FSTAB文件
可以参考:实验误删除 initramfs
注意:正常级别下,最后启动一个服务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/mingettytty1
2:2345:respawn:/usr/sbin/mingettytty2
...
6:2345:respawn:/usr/sbin/mingettytty6mingetty会自动调用login程序
x:5:respawn:/etc/X11/prefdm -nodaemon
总结:/sbin/init--> (/etc/inittab) --> 设置默认运行级别--> 运行系统初始脚本、完成系统初始化--> (关闭对应下需要关闭的服务)启动需要启动服务--> 设置登录终端
CentOS 6 init程序为: upstart, 其配置文件:
/etc/inittab, /etc/init/*.conf,配置文件的语法遵循upstart配置文件语法格式,和CentOS5不同
hexdump -C -n 512 /dev/sda
512字节
CentOS 6启动流程:
POST --> Boot Sequence(BIOS) --> Boot Loader --> Kernel(ramdisk) --> rootfs--> switchroot--> /sbin/init-->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别--> 系统初始化脚本rc.sysinit--> 关闭或启动对应级别的服务--> 启动终端
grub: GRandUnified Bootloader
grub 0.97: grub legacy
grub 2.x: grub2
grub legacy:
stage1: mbr
stage1_5:mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统
stage2:磁盘分区(/boot/grub/)
自己理解:
找boot 之后看到boot上面分区是ext4系统之后去找根但是不知道根在那就去找stage1_5/boot/grub/grub.conf这个文件,之后去找根
hexdump -C -n 512 /dev/sda 查看 后面加-V 更详细
重启后机器会直接光盘启动(一看446个字节是空的不可引导只好就找别的,如果光盘没挂载彻底起不来错误提示)
修复还需光盘引导 救援模式修复
点击shell start shell之后
chroot /mnt/sysimage 切换跟
greb-install /dev/sda 修复完成
mv /boot/grub /app/ 移走
执行命令grub
现在删除10扇区
1. dd if=/dev/zero of =/dev/sda bs=1 count=5120 skip=512 seek=512
2. 重启之后错误提示是屏幕是黑屏。。
3. 修复还需光盘引导 救援模式修复
点击shell start shell之后
chroot /mnt/sysimage 切换跟
greb-install /dev/sda 修复完成(1 1.5 2 阶段全部都能修复)
这里 修复好了 稍等下sync 因为它写到缓存 立即重启有可能会出现问题
这个系统是个干净系统所以能启动没有进行过修复(新系统之前grub2阶段文件 没在/boot/grub里面 执行过修复命令后会把所有文件放到/boot/grub里面 所有没东西了 就启动失败)
安装grub:
(1) grub-install
安装grub stage1和stage1_5到/dev/DISK磁盘上,并复制GRUB相关文件到DIR/boot目录下
grub-install --root-directory=DIR /dev/DISK
详解:DIR 是boot分区的上级目录 /根 ;/dev/DISK硬盘上不写在分区上是因为 grub 1阶段不属于任何分区446字节不属于任何分区 ;所以不能
(2) grub
grub> root (hd#,#)
hd硬盘的意思第一个#代表boot在那认为/boot为跟 例:root (hd0,0)、boot分区在第0个硬盘第一个分区
grub> setup (hd#) #/boot分区在第0个硬盘
配置文件:/boot/grub/grub.conf<--/etc/grub.conf
stage2及内核等通常放置于一个基本磁盘分区
grub的命令行接口
help: 获取帮助列表
help KEYWORD: 详细帮助信息
find (hd#,#)/PATH/TO/SOMEFILE:
root (hd#,#)
kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可添加许多内核支持使用的cmdline参数
例如:max_loop=100 selinux=0 init=/path/to/init
initrd/PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk
boot: 引导启动选定的内核
cat /proc/cmdline
内核参数
内核参数文档:/usr/share/doc/kernel-doc-2.6.32/Documentation/kernel-parameters.txt
识别硬盘设备(hd#,#)
hd#: 磁盘编号,用数字表示;从0开始编号
(hd0,0) 第一块硬盘,第一个分区
手动在grub命令行接口启动系统
grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE roroot=/dev/DEVICE
grub> initrd/initramfs-VERSION-RELEASE.img
grub> boot
配置文件:/boot/grub/grub.conf
default=#: 设定默认启动的菜单项;落单项(title)编号从0开始
timeout=#:指定菜单项等待选项选择的时长
splashimage=(hd#,#)/PATH/XPM_FILE:菜单背景图片文件路径
password [--md5] STRING: 启动菜单编辑认证
hiddenmenu:隐藏菜单
title TITLE:定义菜单项"标题", 可出现多次
root (hd#,#):查找stage2及kernel文件所在设备分区;为grub的根
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核
initrd/PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件
password [--md5|--encrypted ] STRING:启动选定的内核或操作系统时进行认证
重新编写 kernel与initrd 这两行顺序
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=54ed9b7b-f7a9-40d4-8bbf-15faed977b03 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
initrd /initramfs-2.6.32-696.el6.x86_64.img
title windows server 2016
破解root口令:启动系统时,设置其运行级别1
第一种:
在选定的kernel后附加1, s, S或single都可以
之后设置新口令passwd 重启完成
第二种:
第三种:
救援模式 直接能看密码是多少
第四种
密码加密
password --md5 加密密码
password --encrypted 加密密码