Error[8]: Undefined offset: 87, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

[+++]

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

[+++]

5.ngix日志切割脚本

[+++]

思路:

[+++]

6.msqyl 主从监控

[+++]

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 88, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

[+++]

5.ngix日志切割脚本

[+++]

思路:

[+++]

6.msqyl 主从监控

[+++]

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 89, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

5.ngix日志切割脚本

[+++]

思路:

[+++]

6.msqyl 主从监控

[+++]

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 90, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

5.ngix日志切割脚本

思路:

[+++]

6.msqyl 主从监控

[+++]

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 91, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

5.ngix日志切割脚本

思路:

6.msqyl 主从监控

[+++]

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 92, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

5.ngix日志切割脚本

思路:

6.msqyl 主从监控

7.expect实现ssh 免密登录

[+++]

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
shell 编程 入门到实战详解_python_内存溢出

shell 编程 入门到实战详解

shell 编程 入门到实战详解,第1张

概述一.shell变量、循环概述Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是Linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调

一. shell变量、循环

概述

Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互 *** 作的一种接口。它接收用户输入的命令,并把它送入内核去执行。内核是linux系统的心脏,从开机自检就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存。Shell是一种应用程序,当用户登录linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,linux内核才能执行该命令。

优势

Shell脚本语言的好处是简单、易学、易用,适合处理文件和目录之类的对象,以简单的方式快速完成某些复杂的事情通常是创建脚本的重要原则,脚本语言的特性可以总结为以下几个方面:

语法和结构通常比较简单。学习和使用通常比较简单,通常以容易修改程序的“解释”作为运行方式,而不需要“编译。程序的开发产能优于运行效能。

Shell脚本语言是linux/Unix系统上一种重要的脚本语言,在linux/Unix领域应用极为广泛,熟练掌握Shell脚本语言是一个优秀的linux/Unix开发者和系统管理员必经之路。利用Shell脚本语言可以简洁地实现复杂的 *** 作,而且Shell脚本程序往往可以在不同版本的linux/Unix系统上通用。

1.基本格式:

Shell脚本的文件名后缀通常是.sh (当然你也可以使用其他后缀或者没有后缀,.sh是为了规范)

程序编写格式:

#!/bin/bash#  注释使用#号

代码示例:

使用vi编辑器编写shell脚本(a.sh不存在则会新建)vi a.sh

进入vi编辑模式后编写执行代码

固定格式,记住就可以了#!/bin/bash执行的代码echo Hello World

赋予权限并执行:

赋予可执行权限chmod +x a.sh执行(调用/bin/bash执行a.sh脚本)./a.shsh a.sh

执行结果:

[root@python ~]# ./a.sh Hello world

bash 语法检查

[root@python ~]# bash -x a.sh + echo Hello worldHello world

2.变量

变量不需要声明,初始化不需要指定类型

2.1 变量命名

只能使用数字,字母和下划线,且不能以数字开头变量名区分大小写建议命令要通俗易懂

注意:变量赋值是通过等号(=)进行赋值,在变量、等号和值之间不能出现空格。

显示变量值使用echo命令(类似于java中的system.out) ,加上变量名,也可以使用{变量名}

变量的申明和使用:

[root@python ~]# num=10[root@python ~]# echo $num10

2.2 变量分类:

Shell变量有这几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

- 只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。- 定义:VAR_name=VALUE- 变量引用:{VAR_name} 或者 VAR_name- 取消变量:unset VAR_name- 只能当前类使用,子类和其他类都无法使用。

在一个bash命令窗口下再使用bash,则变成了子进程,本地变量不会被这个子进程所访问

[root@python ~]# num=10[root@python ~]# echo $num10[root@python ~]# bash[root@python ~]# echo $unm[root@python ~]#

2.3 环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_name=VALUE

对所有shell进程都有效需要配置到配置文件中

[root@python ~]# vim /etc/profile[root@python ~]# source /etc/profile

自定义的环境变量:

[root@python ~]# export name=xiaoming[root@python ~]# echo $namexiaoming[root@python ~]# bash[root@python ~]# echo $namexiaoming

2.1 局部变量

在函数中调用,函数执行结束,变量就会消失对shell脚本中某代码片段有效定义:local VAR_name=VALUE

2.2 位置变量

比如脚本中的参数:

linux中变量$#,$@,
[root@python ~]# cat variable.sh #!/bin/shecho "number:$#"echo "scname:
[root@python ~]# ./variable.sh number:0scname:./variable.shfirst :second:argume:show parm List:show process ID:1445show precomm stat: 0
"echo "first :"echo "second:"echo "argume:$@"echo "show parm List:$*"echo "show process ID:$$"echo "show precomm stat: $?"
,,,$*,$$,$?的含义?$# 是传给脚本的参数个数
[root@python ~]# echo '$name'$name
 是脚本本身的名字 是传递给该shell脚本的第一个参数 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$ 是脚本运行的当前进程ID号linux中变量$#,$@,
[root@python ~]# echo "$name"xiaoming
,,,$*,$$,$?的含义$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

编写脚本:

[root@python ~]# echo `$name`bash: xiaoming: command not found

执行示例:

for ((i=0;i<10;i++))do  ...Done

引号

Shell编程中有三类引号:单引号、双引号、反引号。

1.’'单引号

不解析变量

for i in 0 1 2 3 4 5 6 7 8 9do...Done

2.""双引号

会解析变量

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

3.``反引号

是执行并引用一个命令的执行结果,类似于$(…)

for i in {0..9}do  ...done

循环

3.1 for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环

格式 1

#!/bin/bashday="sun mon  tue wen fri sat "for x in $daydo	echo "the day is : $x"done

格式 2

while 测试条件do循环体done

示例

[root@python ~]# cat while.sh #!/bin/bashnum=0while [ $num -lt 10 ]doecho $numlet num=$num+1done

格式 3

[root@python ~]# sh while.sh 0123456789

注意:for i in {0…9} 等于for i in {0…9…1} , 第三个参数为跨步

示例

test EXPR[ EXPR ]:注意中括号和表达式之间的空格

3.2 while循环

适用于循环次数未知,或不便用for直接生成较大的列表时

格式

-gt:大于:-lt:小于-ge:大于等于-le:小于等于-eq:等于-ne:不等于

如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。

=:等于,例如判断变量是否为空 [ "$str" =  "" ] 或者[ -z $str ]!=:不等于

打印结果

[root@python ~]# cat str.sh #!/bin/bashnum1=4num2=5str1=Alicestr2=Bobif [ $num1 -gt $num2 ]thenecho num1 large than num2elseecho num1 lower than num2fiif [ -z $str1 ]thenecho str1 is emptyelseecho str is not emptyfi

4.循环控制

4.1 循环控制命令——break

break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环

4.2 循环控制命令——continue

continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件

5 条件

5.1 bash条件测试

格式:

[root@python ~]# sh str.sh num1 lower than num2str is not empty

5.2 整型测试:

 if 测试条件;then选择分支fi#!/bin/bashif [ $USER != root ];thenecho "erro:not root user,permission deny"exit 127fi

例如[ num1 -gt num2 ]或者test num1 -gt num2

5.3 字符串测试:

if 测试条件  then   选择分支1   else   选择分支2 fi

示例:

 if 条件1; then           分支1 elif 条件2; then           分支2 elif 条件3; then           分支3          ... else           分支n fi

执行结果:

#!/bin/bashread -p "input a file name:" file_nameif [ -d $file_name ];then	echo "$file_name is a directory"elif [ -f $file_name ];then	echo "$file_name is a file"elif [ -c $file_name ];then	echo "$file_name is a devices"else	echo "$file_name is unkNown file"fi7.**Case判断**

6.判断

6.1 单分支

case 变量引用 in               PATTERN1)                         分支1                         ;;               PATTERN2)                         分支2                         ;;               ...               *)                         分支n                         ;;               esac

6.2 双分支

[root@python ~]# cat case.sh #!/bin/bashnum=10case $num in	1)		echo 1			;;	2)		echo 2			;;	10)		echo 10			;;	*)		echo somethine else			;;esac

6.3 多分支

let varname=算术表达式varname=$[算术表达式]varname=$((算术表达式))varname=`expr $num1 + $num2`使用这种格式要注意两个数字和+号中间要有空格。

示例:

[root@centos7 ~]# num=2[root@centos7 ~]# let num=$num+1[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$[ $num+1 ][root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=$(($num+1))[root@centos7 ~]# echo $num3[root@centos7 ~]# num=2[root@centos7 ~]# num=`expr $num + 1`[root@centos7 ~]# echo $num3

7.case语句会使得语法结构更清晰

7.1格式

-a 与-o 或! 非如if [ 条件A -a 条件B ]

PATTERN :类同于文件名通配机制,但支持使用|表示或者

a|b:a或者b

*:匹配任意长度的任意字符

?:匹配任意单个字符

[a-z]:指定范围内的任意单个字符

7.2示例

[root@python ~]# cat num_1.sh #!/bin/bashnum1=10num2=20num3=15if [ $num1 -lt $num3 -a $num2 -gt $num3 ]then	echo "num is between 10 and 20"else	echo "something else"fi

8.算术运算

#!/bin/bashnum1=10num2=20num3=15if [ $num1 -ge $num3 -o $num2 -lt $num3 ]then        echo "num is between 10 and 20"else        echo "something else"fi

8.1示例

function 函数名(){...}引用自定义函数文件时,使用source  func.sh有利于代码的重用性函数传递参数(args[1]代表Shell中的)函数的返回值,只能是数字[root@python ~]# cat func.sh #!/bin/bashfunction func(){	echo this is function}func

8.2 逻辑运算符

8.2.1逻辑与

需要用到shell中的逻辑 *** 作符

[root@python ~]# cat  func2.sh#!/bin/bashsource /root/func.shfunc

示例

read VAR_name

8.2.2 逻辑或

示例

#表示输入时的提示字符串:read -p "Enter your name:" VAR_name[root@python ~]# read -p  "Enter you name:" nameEnter you name:[root@python ~]# read -t 5 -p  "Enter you name:" nameEnter you name:[root@python ~]# # -t表示输入等待的时间read -t 5 -p "enter your name:" VAR_name[root@python ~]# read -s -p  "Enter your password:" passEnter your password:

9.自定义函数

9.1 格式:

-r 只读-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。-a 数组

9.2.函数的调用:

[root@python ~]# num=10[root@python ~]# declare -r num[root@python ~]# num=20bash: num: Readonly variable[root@python ~]#

9.3 read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。

格式

[root@python ~]# num4=10[root@python ~]# num4=$num4+1[root@python ~]# echo $num410+1[root@python ~]# declare  -i num5[root@python ~]# num5=10[root@python ~]# num5=$num5+1[root@python ~]# echo $num511

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

[root@python ~]# declare  -a arr[root@python ~]# arr=(1 2 3 4 5)[root@python ~]# echo ${arr[*]}1 2 3 4 5

9.4 declare

用来限定变量的属性

${#VAR_name}[root@python ~]# name=Alice[root@python ~]# echo ${#name}5

示例:

9.4.1 只读

${variable:offset:length}或者${variable:offset}[root@python ~]# name=Alice[root@python ~]# echo ${name:0:3}Ali

9.4.2 整数

${variable: -length}:注意冒号后面有空格[root@python ~]# name=Alice[root@python ~]# echo ${name:2}ice

9.4.3 数组

${variable^^}[root@python ~]# name=Alice[root@python ~]# echo ${name^^}AliCE

字符段 *** 作

10.1 获取长度:

${variable,,}[root@python ~]# name=Alice[root@python ~]# echo ${name,,}alice

10.2 字符串截取

${ARRAY[index]}:查看数组指定角标的元素${ARRAY}:查看数组的第一个元素${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素

10.3 取尾部的指定个数的字符

${#ARRAY[*]}${#ARRAY[@]}

10.4 大小写转换

小—>大:

${#ARRAY[0]}注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}

大—>小

${ARRAY[@]:offset:length}

10.5 数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM一次对多个元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

使用read命令read -a ARRAY_name查看元素

unset ARRAY[index]

获取数组的长度

[root@python ~]# declare -a arr2[root@python ~]# arr2=(a b c d )[root@python ~]# arr2[1]=x[root@python ~]# echo ${arr2[*]}a x c d[root@python ~]# echo ${#arr2[*]}4[root@python ~]# echo ${#arr2[1]}1[root@python ~]# echo ${arr2[1]}x

获取数组内元素的长度

[root@python ~]# echo `date +%Y-%m-%d-%H:%M:%s`2018-08-25-14:07:16[root@python ~]# echo `date +%s`1535220472[root@python ~]# echo `date --date='2009-01-01 11:11:11'`Thu Jan 1 11:11:11 EST 2009[root@python ~]# echo `date --date='3 days ago'`Wed Aug 22 14:10:28 EDT 2018

从数组中获取某一片段之内的元素( *** 作类似于字符串 *** 作)

格式:

test.sh &

offset:偏移的元素个数length:取出的元素的个数${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素${ARRAY[@]:offset}:取出数组中偏移量后的所有元素

数组删除元素:

nohup test.sh &

示例:

1. ls >file 或者 ls 1>file(ls >>file)2. lk 2>file(lk是一个错误命令)3. ls >file 2>&14. ls > /dev/null(把输出信息重定向到无底洞)


二.shell 常用命令及参数

1.date

显示当前时间

格式化输出 +%Y-%m-%d格式%s表示自1970-01-01 00:00:00以来的秒数指定时间输出 --date=‘2009-01-01 11:11:11’指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)

示例:

command  >/dev/null 2>&1

2.后台运行脚本

在脚本后面加一个&

* * * * * bash /root/bash.sh

这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到linux HUP信号(hangup)信号从而关闭其所有子进程 ]

3.nohup命令

不挂断的运行命令,忽略所有挂断(hangup)信号

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh

nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。nohup会在当前执行的目录生成一个nohup.out日志文件

4.标准输入、输出、错误、重定向

标准输入、输出、错误可以使用文件描述符0、1、2引用

使用重定向可以把信息重定向到其他位置

[root@python ~]# crontab  -l* * * * * bash /root/bash.sh[root@python ~]# crontab  -rYou have new mail in /var/spool/mail/root[root@python ~]# crontab  -lno crontab for root

示例

[root@python ~]# tail -f /var/log/cron

5.Crontab定时器

linux下的定时任务编辑使用crontab -e一共6列,分别是:分 时 日 月 周 命令

示例 表示每分钟执行一次bash /root/bash.sh 命令

[root@python ~]# tail -f /var/spool/mail/root (查看crontab执行的情况)

查看定时任务

[root@python ~]# service crond status

删定时任务

[root@python ~]# service crond start

查看crontab执行日志

基本格式 :*  *  *  *  *  command分 时  日  月   周   命令第1列表示分钟1~59 每分钟用*或者 */1表示第2列表示小时1~23(0表示0点)第3列表示日期1~31第4列表示月份1~12第5列标识号星期0~6(0表示星期天)第6列要运行的命令

必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)

30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache。45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每月1、10、22日的4 : 45重启apache。10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart上面的例子表示每星期六的11 : 00 pm重启apache。* */1 * * * /usr/local/etc/rc.d/lighttpd restart每一小时重启apache* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart晚上11点到早上7点之间,每隔一小时重启apache0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart每月的4号与每周一到周三的11点重启apache0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart一月一号的4点重启apache

查看cron服务状态

交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。 非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。 登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为"-",指明这是一个login shell。比如对bash而言,启动参数为"-bash"。 非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有'-'前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。 一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。 当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo 
Optimization_host.sh#!/bin/bash#此脚本在centos6.8上面试运行没有问题,其他版本慎用!!!#注意:#1、缩进问题#2、严谨性#3、精简至上原则   Ipaddr(){echo -e "3[32;1m========================配置ip地址以及主机名称======================================3[0m"read -p "请输入你的ip地址:" IPADDRread -p "请输入你的子网掩码:" NETMASKread -p "请输入你的网关地址:" GATEWAYread -p "请输入你的DNS1:" DNS1sed -i  '/^ONBOOT/s/no/yes/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i  '/^BOOTPROTO/s/dhcp/static/' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^IPADDR/s/[0-9].\+/$IPADDR/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^NETMASK/s/[0-9].\+/$NETMASK/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^GATEWAY/s/[0-9].\+/$GATEWAY/ "  /etc/sysconfig/network-scripts/ifcfg-eth0sed -i "/^DNS1/s/[0-9].\+/$DNS1/ "  /etc/sysconfig/network-scripts/ifcfg-eth0service  network restart >&/dev/nullPing -c 3 -w 5 www.baIDu.com >&/dev/nullif  [[ $? != 0 ]];thenecho " 不能上网请检查配置 "elseecho -e "3[32;1m=====================NetWork Already Configure Finish ============================3[0m"fisleep 2}Ip_hostname(){echo -e "3[32;1m==========================配置主机名称==============================================3[0m"read  -p "请输入你的主机名称:" HOSTnamesed -i '3,$d' /etc/hostssed -i '2,$d' /etc/sysconfig/networksed -i  '/^HOSTname.*$/d' /etc/hostsecho "HOSTname=$HOSTname" >> /etc/sysconfig/networkIPADDR=`ip a  | grep "global eth0" | awk '{print }' | awk -F "/" '{print }'`echo -e "$IPADDR\t$HOSTname" >>/etc/hostsecho -e "3[32;1m===========================主机名配置成功==========================================3[0m"echo ""sleep 2}# yum_163ConfigYum(){echo -e "3[32;1m===========================更新为国内YUM源==========================================3[0m"cd /etc/yum.repos.d/    Ping -c 1 www.163.com>/dev/nullif [ $? -eq 0 ];then        mv CentOS6-Base-163.repo{,.$(date +%F)}wget -q  http://mirrors.163.com/.help/CentOS6-Base-163.repo >/dev/nullsleep 2        sed -i "s/$releasever/6.8/g" CentOS6-Base-163.repo        #sed -i '/s/$releasever/6.8/g' CentOS6-Base-163.repo   #此处可提升为判断系统版本号,给出不同的版本节点elseecho "无法连接网络!!!!"exit $?fiecho -e "3[32;1m============================正在更新YUM源配置=======================================3[0m"yum clean all >>/dev/nullyum List >>/dev/null#action "配置国内YUM完成"  /bin/trueecho -e "3[32;1m======================================配置YUM源完成===============================3[0m"echo ""sleep 2}#time syncSyncSysTime(){echo -e "3[32;1m=========================================配置时间====================================3[0m"  \cp /var/spool/cron/root /var/spool/cron/root.$(date +%F) 2>/dev/null  NTPDATE=`grep ntpdate /var/spool/cron/root 2>/dev/null |wc -l`  if [ $NTPDATE -eq 0 ];then    echo "#times sync by lee at $(date +%F)" >>/var/spool/cron/root    echo "*/5 * * * * /usr/sbin/ntpdate time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root  fi#action "配置时间同步完成" /bin/trueecho -e "3[32;1m=========================================配置时间完成====================================3[0m"echo ""  sleep 2}#Charset zh_CN.UTF-8InitI18n(){echo -e  "3[32;1m======================================更改为中文字符集===================================3[0m"  \cp /etc/sysconfig/i18n /etc/sysconfig/i18n.$(date +%F)  echo "LANG="zh_CN.UTF-8"" >/etc/sysconfig/i18n  source /etc/sysconfig/i18n  echo '#cat /etc/sysconfig/i18n'  grep LANG /etc/sysconfig/i18n#action "更改字符集zh_CN.UTF-8完成" /bin/trueecho -e "3[32;1m====================================更改为中文字符集完成===================================3[0m"echo ""  sleep 2}#Close Selinux and IptablesFirewall(){echo -e "3[32;1m======================================禁用SEliNUX及关闭防火墙=============================3[0m"cp /etc/selinux/config /etc/selinux/config.$(date +%F)  /etc/init.d/iptables status >>/dev/null  if [ $? -eq 0 ];then #判断防火墙是否开启,开启时返回值是0    /etc/init.d/iptables stop >>/dev/null  fi$(cat /etc/selinux/config |grep SEliNUX=enforcing)if [ $? -eq 0 ] ;then    sed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/g' /etc/selinux/config    setenforce 0fi#getenforce#action "禁用selinux及关闭防火墙完成" /bin/trueecho -e "3[32;1m======================================禁用SEliNUX及关闭防火墙完成=============================3[0m"echo ""  sleep 2}Yum(){echo -e "3[32;1m======================================安装常用软件=============================3[0m"yum  install -y lrzsz  nptdate    bash-completion  wget echo ""  sleep 2}echo -e "3[32;1m======================================安装常用软件完成=============================3[0m"Core(){echo -e "3[32;1m======================================内核参数调整=============================3[0m"# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################################################################################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################################################################################################* - nofile 1048576* - nproc  65536* - stack  1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################################################################################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOFecho -e "3[32;1m======================================内核参数调整完毕=============================3[0m"#menu2menu2(){while truedoclearcat << EOF----------------------------------------|****Please Enter Your Choice:[0-6]****|----------------------------------------(1) 配置ip地址以(2) 配置为国内YUM源镜像(3) 设置时间同步(4) 配置中文字符集(5) 禁用SEliNUX及关闭防火墙(6) 配置主机名称(0) 返回上一级菜单EOFread -p "Please enter your Choice[0-6]: " input2case "$input2" in  0)  clear  break  ;;  1)  Ipaddr  ;;  2)  ConfigYum  ;;  3)  SyncSysTime  ;;  4)  InitI18n  ;;  5)  Firewall  ;;  6)  Ip_hostname  ;;  *)  Warning  ;;esacdone}#menumain(){while truedoclearecho "========================================"echo '          linux Optimization            '   echo "========================================"cat << EOF|-----------System Infomation-----------| DATE       :$DATE| HOSTname   :$HOSTname| USER       :$USER| IP         :$IPADDR| disK_USED  :$disK_SDA| cpu_AVERAGE:$cpu_uptime----------------------------------------|****Please Enter Your Choice:[1-3]****|----------------------------------------(1) 一键优化(2) 自定义优化(3) 退出EOF#choiceread -p "Please enter your choice[0-3]: " input1    case "$input1" in    1)        Ipaddr    ConfigYum    SyncSysTime    InitI18n    Firewall    Ip_hostname        ;;    2)        menu2        ;;    3)        clear        break        ;;    *)      Warning   ;;    esac  done}Warning(){echo "----------------------------------"  echo "|          Warning!!!            |"  echo "|   Please Enter Right Choice!   |"  echo "----------------------------------"  sleep 2((ErrorNo+=1))    if [ $ErrorNo -eq 3 ];then  #判断错误次数,已达到自动退出目的        echo -e '3[31;1mError So Much ,The Script  Exiting!3[0m'        sleep 5        exit    fi  clear}if $UID != 0 ;thenecho 'must use Root run this script!'else#获取一些初始变量,磁盘使用情况未配置    ErrorNo=0    DATE=$(date +%F)    IPADDR=`ifconfig |grep Bcast|awk '{print }'|awk -F: '{print }'`    disK_SDA=`df -hT | grep '/$' | awk '{print }'`       cpu_uptime=`uptime|awk -F: '{print }'`mainfi
。 注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。

启动cron服务

centos 7 优化 #!/bin/bash# 服务优化grep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenServices=$(chkconfig --List | grep '0' | awk '{print }' | grep -Ev 'sshd|network|crond|syslog|ntpd')for Service in $Servicesdoservice $Service stopchkconfig --level 0123456 $Service offdoneelseServices=(atd avahi-daemon cups dmraID-activation firewalld irqbalance kdump mdmonitor postfix)for Service in ${Services[*]}dosystemctl disable ${Service}systemctl stop ${Service}donesystemctl enable rc-localfi# 内核参数调优grep -q "fs.file-max = 6815744" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################vm.swappiness = 0vm.overcommit_memory = 1net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216net.core.somaxconn = 60000net.core.netdev_max_backlog = 60000net.ipv4.tcp_max_orphans = 60000net.ipv4.tcp_orphan_retrIEs = 3net.ipv4.tcp_max_syn_backlog = 60000net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.ip_local_port_range = 1024 65500net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_synack_retrIEs = 1net.ipv4.tcp_syn_retrIEs = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_mem = 786432 1048576 1572864fs.aio-max-nr = 1048576fs.file-max = 6815744kernel.sem = 250 32000 100 10000kernel.pID_max = 65536fs.inotify.max_user_watches = 1048576kernel.kptr_restrict = 1kernel.ctrl-alt-del = 1EOFsysctl -p# 提高系统打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "* - nofile 1048576" /etc/security/limits.conf || cat >> /etc/security/limits.conf << EOF########################################* - nofile 1048576* - nproc 65536* - stack 1024EOF# 提高Shell打开文件数、打开进程数限制,减小默认栈空间大小限制grep -q "ulimit -n 1048576" /etc/profile || cat >> /etc/profile << EOF########################################ulimit -n 1048576ulimit -u 65536ulimit -s 1024alias grep='grep --color=auto'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%s "EOF# 禁用并关闭selinuxsed -i 's/SEliNUX=enforcing/SEliNUX=Disabled/' /etc/selinux/configsetenforce 0# 优化SSH服务sed -i 's/.*UsednS yes/UsednS no/' /etc/ssh/sshd_configsed -i 's/.*GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config#sed -i '/^PasswordAuthentication/s/yes/no/' /etc/ssh/sshd_configgrep -q '7.' /etc/redhat-releaseif [ $? -ne 0 ]; thenservice sshd restartelsesystemctl restart sshd.servicefi# 脚本目录加入PATH环境变量grep -q "/root/script" $HOME/.bashrc || cat >> $HOME/.bashrc << EOF########################################export PATH=/root/script:$PATHEOFmkdir -p /root/script /root/src# 挂载tmpfs文件系统mount --bind /dev/shm /tmpgrep -q "mount --bind /dev/shm /tmp" /etc/rc.local || echo "mount --bind /dev/shm /tmp" >> /etc/rc.local

基本示例:

对刚安装完成的虚拟主机进行优化处理,简化工作流程对服务进行优化对防火墙 selinux进行优化字符编码进行优化network进行优化ssh 进行优化yum 源进行优化date 时间进行优化

crontab 示例:

#/bin/bash#by innocence_caosm#源码自动安装zabbix客户端脚本。#需要把zabbix安装包放在/tmp/ 下面执行。 #安装gcc cc插件#此脚本已在centos6.5以及6.8版本测试过,其他版本慎用。yum install -y gcc cc#需要注意修改的参数server_ip=133.1.11.103version=zabbix-3.2.7#检查zabbix用户是否存在user=zabbixgroup=zabbix#create group if not existsegrep "^$group" /etc/group >& /dev/nullif [ $? -ne 0 ]thengroupadd $groupfi#create user if not existsegrep "^$user" /etc/passwd >& /dev/nullif [ $? -ne 0 ]thenuseradd -g $group $user -s /sbin/nologinecho zabbix |passwd --stdin $user >& /dev/nullfi#检查原有zabbix服务,如果有则停掉ps -ef |grep zabbix|grep -v grepif [ $? -eq 0 ]then/etc/init.d/zabbix-agent stop || /etc/init.d/zabbix-agentd stopfi#编译安装tar -zxvf /tmp/$version.tar.gz -C /usr/local/src/;cd /usr/local/src/$version/./configure --prefix=/usr/local/$version/ --enable-agentmake&&make install#修改配置文件sed -i.bak 's/127.0.0.1/$server_ip/g' /usr/local/$version/etc/zabbix_agentd.confhostname=cat /etc/sysconfig/network | sed -n '2p' | awk -F'=' '{print }'sed -i "s/Hostname=Zabbix server/Hostname="$hostname"/g" /usr/local/$version/etc/zabbix_agentd.conf#配置init.d启动cp /usr/local/src/$version/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/zabbix_agentdsed -i 's/BASEDIR=\/usr\/local/BASEDIR=\/usr\/local\/$version/g' /etc/init.d/zabbix_agentd#配置开机启动chkconfig --add zabbix_agentdchkconfig zabbix_agentd on/etc/init.d/zabbix_agentd start#查看zabbix启动netstat -lnp |grep zabbixif [ $? -eq 0 ]thenecho "Zabbix agent install have completed."fi


三. 登录Shell和交互shell

由于需要批量部署zabbix 客户端,简化 *** 作流程,在这样的条件下写了这个脚本。1.安装系统所需要的依赖插件2.把客户端源码放在指定位置进行解压处理3.检查系统用户是否存在4.对配置进行修改处理5.启动进行检测

四.shell 应用示例

1.系统优化脚本

需求:对CentOS6系统进行配置优化

[root@localhost opt]# cat web_url.sh #!/bin/bashfor i in `cat web_url`docurl=`curl -I -s $i |head -1|cut -d " " -f2`if [ "$curl" == "200" ];then    echo curl $i is okelse    echo "$i is fail" | mail -s "web fail url"  yunwei@jIDuo365.comfidone[root@localhost opt]# cat web_urlhttp://192.168.0.123:8080/lemon/portal/index.dohttp://192.168.0.123:8080/photo

CentOS7** 系统优化脚本

由于内网环境处于调试初期阶段,服务不稳定,需要对指定的几个url进行做监控处理。1.把需要尽快的URL地址写到文档中2.运用for循环来遍历URL地址3.检测状态码是否正常,正常则打印出来,不正常则把url 信息通过邮箱发送给管理员

思路:

#!/bin/bash#此脚本用于统计Nginx日志距离当前时间15分钟之内不同接口的访问量统计LOG=/usr/local/Nginx/logs/interface.access.logTMP=/tmp/url.tmpURLSTATS=/var/log/interface_urlstats.logRECEIVERS="xmwang@etone.tv bliu@etone.tv jfxiao@etone.tv"#删除临时统计文件[ -f $TMP ] && rm -fr $TMPfor i in `seq 20`do	d=`date +%d/%h/%Y:%H:%M  -d "$i minutes ago"`	#将每个时间段的URL进行统计并追加到临时文件	awk -v b="$d" '{if ( ~ b)a[]++}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $LOG >> $TMPdone#将汇总到临时文件的URL统计进行汇总if [ -s $TMP ];then	awk '{a[]+=;}END{for(i in a)printf("%-42s %-d\n", i,a[i])}' $TMP | sort -nr -k2 > $URLSTATS	mail -s "$(date +%F-%H:%M) 20分钟内URL访问量统计"  "$RECEIVERS" <$URLSTATSelse	echo "需要统计的时间段日志文件没有被成功处理"fi1. 根据seq循环15次并调用date获取最近的20分钟的时间,2. 使用awk进行过滤日志并格式化打印,然后结合sort排序,3. 最终过滤内容通过mail发送邮件

2.自动部署zabbix 脚本

#!/bin/shset -xlogs_path="/usr/local/Nginx/logs"oldlogs_path="/Nginx_oldlogs/"for i in `ls $logs_path/* |grep -v Nginx.pID |grep -v oldlogs`        do        mv "$i"  "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")        mv "$i"_${HOS}_$(date -d "yesterday" +"%Y%m%d")  $oldlogs_pathdone#向Nginx主进程发信号重新打开日志Nginx_pID= `ps -ef |grep Nginx|grep master|awk '{print }'`kill -USR1 $Nginx_pID/usr/local/Nginx/sbin/Nginx -t && /usr/local/Nginx/sbin/Nginx -s reloadsleep 2#docker exec -it tengine  /usr/local/Nginx/sbin/Nginx -s reopen#sleep 1 #clear the expired logscd $oldlogs_path#find ./ -mtime +90 -exec rm -rf {} \;echo "The old logfiles is deleted!!"

思路:

对日志进行管理,结合cron每天进行切割,1.定义日志的位置,及存储的位置。2.对日志进行重新命名 移动到指定的位置3.向Nginx主进程发信号重新打开日志4.对旧的日志进行删除处理

3.监控url 地址

#!/bin/bash USER=bak PASSWD=123456 IO_sql_STATUS=$(MysqL -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":");print 
#!/usr/bin/expectspawn ssh root@192.168.10.10set timeout 10   //设置超时时间expect "*password:"send "nbc@123\r" //输入密码expect { 	"*yes/no" { send "yes\r"; exp_continue}  //第一次ssh连接会提示yes/no,继续 	 "*password:" { send "$password\r" }  //出现密码提示,发送密码} interact //交互模式,用户会停留在远程服务器上面.
}') #gsub去除冒号后面的空格 for i in $IO_sql_STATUS; do  THREAD_STATUS_name=${i%:*}  THREAD_STATUS=${i#*:}  if [ "$THREAD_STATUS" != "Yes" ]; then  echo "Error: MysqL Master-Slave $THREAD_STATUS_name status is $THREAD_STATUS!"  fi done

思路:

4.Nginx日志距离当前时间20分钟之内不同接口的访问量统计

5.ngix日志切割脚本

思路:

6.msqyl 主从监控

7.expect实现ssh 免密登录

公司内常用脚本案例将会在近期更新,在学习脚本过程中遇到任何问题,欢迎交流学习。

总结

以上是内存溢出为你收集整理的shell 编程 入门实战详解全部内容,希望文章能够帮你解决shell 编程 入门到实战详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1187472.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存