Mac OS,Linux 自带了shell阐明器,Windows比较麻烦,由于Win7专业版和旗舰版默认安装PowerShell,标准版和家庭版中就没有安装的,为了方便建议安装cygwin
PHP、Python 也可以作为Shell编程PHP、Python是属于高等编程措辞,但是也可以做Shell编程,由于只要有阐明器,也可以用作脚本编程
如下是一个Python Shell Script示例(假设文件名叫op_python_base.py):
#!/usr/bin/env python3 //见告Python从系统环境中找python# -- coding: utf-8 -- //设置为UTF-8编码for index in range(10): print(index);复制代码
如下是一个PHP Shell Script示例(假设文件名叫op_php_base.php):
#!/usr/bin/php<?phpfor($i=0 ;$i<10; $i++){ echo $i;}?>复制代码为什么要学习Shell
既然PHP、Python都可以用来写脚本编程,那为什么还要学习陌生、晦涩难懂的Shell,紧张有一下几个缘故原由
环境兼容性,Win7专业版和旗舰版默认安装PowerShell,标准版和家庭版中就没有安装的,其他主流的操作系统都预制了Shell阐明器,以是利用sh、bash编写,供应给其他人利用是非常方便的,但是PHP、Python 等等须要安装相应的环境如果你想做一些定时任务比如说检测进程是否存在,自动备份,或者说自动支配环境、做事器之间的数据同步等等sh、bash会是你最好的选择sh与bashsh: Bourne shell,POSIX(Portable Operating System Interface)标准的shell阐明器,它的二进制文件路径常日是/bin/sh
bash: Bash是Bourne shell的替代品,属GNU Project,二进制文件路径常日是/bin/bash
第一个shell脚本
我们先来看一个例子
我相信写过代码的童鞋,该当对下面的代码很熟习并不陌生,(假设文件名叫op_base.sh):
#!/usr/bin/env bashmkdir codecd codefor ((i=0; i<3; i++)); do touch test_${i}.txt echo \"大众shell很大略\"大众 >> test_${i}.txtdone复制代码
第一行:从系统path中探求指定脚本的阐明程序 第二行:创建 名叫code文件夹 第三行:进入创建的文件夹 第四行:for循环3次 第四行:创建文件 第五行:往创建的文件中写入信息 第六行:结束循环
mkdir, touch,cd,touch,echo都是系统命令,在命令行下可以直接实行 for, do, done 是shell脚本措辞 for循环的语法
编写Shell
新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本实行,见名知意就好,如果你用php,扩展名为php,如果你用Python,扩展名为python
第一行一样平常是这样:
#!/usr/bin/php#!/usr/bin/env python3#!/usr/bin/env bash复制代码
#!”是一个约定的标记,它见告系统这个脚本须要什么阐明器来实行 /env 是系统的PATH目录中查找
运行 Shell 脚本有两种方法:
作为可实行程序
chmod +x op_base.sh./op_base.sh复制代码
第一行设置 op_base.sh可实行权限 第二行实行op_base.sh
作为参数
/bin/sh op_base.sh复制代码
变量
定义变量时,变量名前不须要加符号和Python一样但是在PHP措辞中变量须要加$,如:
my_name=\"大众jack\公众my_name='jack';复制代码
ps: 变量名和等号之间不能有空格,变量后面不能有;
Shell中的引号和PHP类似,字符串可以用单引号,也可以用双引号
单引号字符串的限定:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的单引号字串中不能涌现单引号(对单引号利用转义符后也弗成双引号:
双引号里可以有变量双引号里可以涌现转义字符但是在Python中单引号和双引号是没有差异,但是Python 还有三个引号,在三个引号内字符都不会被转义
利用变量
对付已经定义过的变量,利用的适宜在前面添加$
echo $my_nameecho ${my_name}复制代码
变量名表面的花括号是可选的,加不加都行,建议利用第二种形式
注释
以“#”开头的行便是注释,会被阐明器忽略。
多行注释
sh里没有多行注释,只能每一行加一个#号。就像这样:
#--------------------------------------------# Author: jack # weibo: OO是有情怀的PM## Notes: 10分钟入门Shell脚本编程## Project home page:# https://github.com/dpm100/fast_guides#--------------------------------------------复制代码
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的差异跟PHP类似
Shell不像其他措辞有php、python 有很多数据类型,在Shell中常用的数据类型字符串数字和字符串(ps: 除了数字和字符串,也没啥其它类型好用了,哈哈)
单引号字符串的限定:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的单引号字串中不能涌现单引号(对单引号利用转义符后也弗成双引号:
双引号里可以有变量双引号里可以涌现转义字符字符串操作
拼接字符串
my_name=\公众jack\"大众;my_age=\"大众20岁\"大众echo $my_name $my_ageecho $my_name$my_age复制代码
获取字符串长度
echo ${#my_name}复制代码
截取字符串
echo ${my_name:0:2}复制代码
Shell 数组
定义数组
在Shell中,用括号来表示数组,数组元素用\"大众空格\"大众符号分割开。定义数组的一样平常形式为:
name=(name1 name2 name3)复制代码
还可以单独定义数组的各个分量:
ary[0]=name1ary[1]=name2ary[3]=name3复制代码
ps: 可以不该用连续的下标,而且下标的范围没有限定
读取数组
读取数组元素值的一样平常格式是:
${数组名[下标]}复制代码
例如:
echo ${name[0]}复制代码
利用@符号可以获取数组中的所有元素,例如:
echo ${name[@]}复制代码
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数length=${#name[@]}echo $length# 或者length=${#name[]}echo $length# 取得数组单个元素的长度lengthn=${#name[n]}echo $length复制代码
Shell 流程掌握
和Java、PHP、Python等措辞不一样,sh的流程掌握不可为空,如(以下为PHP流程掌握写法):
<?phpif (isset($_GET[\"大众q\"大众])) { search(q);}else { // 不做任何事情}复制代码
在sh/bash里可不能这么写,如果else分支没有语句实行,就不要写这个else
if
if condition1then command1elif condition2 then command2else commandNfi复制代码
例子:
#!/usr/bin/env basha=1b=2if [ $a == $b ] then echo \"大众a 即是 b\"大众 elif [ $a -gt $b ] then echo \"大众a 大于 b\"大众 elif [ $a -lt $b ] then echo \公众a 小于 b\"大众 else echo \"大众没有符合的条件\公众 fi复制代码
for 循环
Shell的for循环和Python 有点类似
Python的for循环
for index in 1,2,3,4,5: print(index);复制代码
Shell的for循环,第一种写法
for index in 1 2 3 4 5; do echo \"大众index=\"大众$indexdone复制代码
Shell的for循环,第二种写法
for ((i=0; i<5; i++)); do echo \公众i=\"大众$idone复制代码
while 语句
while循环用于不断实行一系列命令,也用于从输入文件中读取数据;命令常日为测试条件。
int=1while(( $int<=5 ))do echo $int let \公众int++\公众done复制代码
Shell结合系统命令sh脚本结合系统命令便有了强大的威力,在字符处理领域,有grep、awk、sed三剑客,grep卖力找出特定的行,awk能将行拆分成多个字段,sed则可以实现更新插入删除等写操作。
例如定时检测nginx、mysql是否被关闭
path=/var/loglog=${path}/httpd-mysql.logname=(apache mysql)exs_init[0]=\"大众service httpd start\"大众exs_init[1]=\公众/etc/init.d/mysqld restart\"大众for ((i=0; i<2; i++)); do echo \"大众检讨${name[i]}进程是否存在\公众 ps -ef|grep ${name[i]} |grep -v grep if [ $? -eq 0 ]; then pid=$(pgrep -f ${name[i]}) echo \"大众`date +\"大众%Y-%m-%d %H:%M:%S\"大众` ${name[$i]} is running with pid $pid\公众 >> ${log} else $(${exs_init[i]}) echo \公众`date +\公众%Y-%m-%d %H:%M:%S\公众` ${name[$i]} start success\公众 >> ${log} fidone复制代码
阐明:检测 nginx、mysql进程是否存在,如果不存在了会自动重新启动。 脚本每次运行会写日志的,没事可以去看看该日志文件,如果进程是不是真的常常性不存在,恐怕就要排查一下深层缘故原由了。
编辑 /etc/crontab 文件
crontab -e复制代码
在文件末了添加一行:
/5 /xxx/check_nginx.sh > /dev/null 2>&1复制代码
上表示每 5 分钟,实行一下脚本 /xxx/check_nginx.sh,个中xxx代表路径
/dev/null 2>&1 的意思是该条shell命令将不会输出任何信息到掌握台,也不会有任何信息输出到文件中。
# For details see man 4 crontabs# Example of job definition:# .---------------- minute (0 - 59)# | .------------- hour (0 - 23)# | | .---------- day of month (1 - 31)# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat# | | | | |# command to be executed复制代码
添加完配置,须要重启才能生效
service crond restart
原文链接:https://juejin.im/post/5a6378055188253dc332130a