shell脚本
1. shell的概念:
shell是一个由C语言所进行编写的一个程序,shell脚本是用户使用linux的桥梁,shell既是一种命令语言,又是一种程序设计的语言
2. shell脚本的结构
shell脚本,是一种为shell所编写的脚本程序
- shell脚本的开头都是以:#!/bin/bash or !/bin/bash 来开头( #!用来告诉系统,这个脚本需要什么解释器来执行,即使用哪一种shell )
- shell的注释:shell是以 # 开头的来表示注释
- shell命令行中的书写规则:一行一条命令 如果一行多个命令,请用分号进行隔开(;)长命令可以使用反斜线字符(\)来进行隔开
3. shell脚本的基础格式:
【打开文本的编辑器(可以使用vi和vim命令来创建该文件),新建一个shell.sh的文件,扩展名字为sh [sh代表的是shell] ,扩展名并不影响脚本执行,起一个让自己可以看的明白的名字就可以,如果你是用php所写的shell脚本,你的扩展名字就用php来起名字就可以了。】
脚本的格式如下图:
4. shell脚本的方法:
- 作为可执行的程序,(请把上面的代码保存,并cd到所相应的目录)请把你所编写的shell脚本,加上一定的权限如下:
- 注意在编写完脚本之后,一定要给脚本加上执行的权限(因为当你编辑完脚本时,只是一个文档文件,只有你给了它的执行权限才可以进行执行。),在执行脚本的时候,一定要写成./shell.sh的格式,而不是shell.sh,运行其他的二进制的程序也是一样的,如果直接写成shell.sh的格式,linux系统会去PATH里群招有没有叫shell.sh的,而只有/bin,/sbin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成shell.sh的格式是不会找到该命令的,要用./shell.sh来告诉系统说,就在当前的目录找(也就是说你所编写的脚本在那个目录中,在你执行这个脚本的时候,写上你的绝对路径。然后进行执行)。
- 作为解释器的参数,这种运行的方式是,直接运行解释器,其参数是shell脚本的文件名,如: /bin/sh shell.sh
shell的变量:
在命令行提示符直接执行env、set查看系统或环境变量。env显示用户环境变量,set显示shell预先定义好的变量以及用户变量,可以通过export导出成用户变量。
$SHELL 默认shell
$HOME 当前用户家目录
$LANG 默认语言
$PATH 默认可执行程序路径
$PWD 当前目录
$UID 当前用户的ID
$USER 当前用户
$HISTSIZE 历史命令大小,可通过HISTTIMEFORMAT变量设置命令执行时间
$RANDOM 随机生成一个0至32767的整数
$HOSTNAME 主机名字
shell的普通变量与临时环境变量:
普通变量:VAR=value
临时变量:export VAR=value
变量引用:$VAR
shell进程的环境作用域是shell进程,当export导入到系统变量时,则作用域是shell进程及其shell子进程。
ps axjf 输出第一列是PPID(父进程的PID),第二列输出的是子进程的PID。当ssh连接shell时,当前终端PPID(-bash)是sshd守护程序的PID(root@pts/0),因此在当前终端下的所有进程的PPID都是-bash的PID,比如执行命令、运行脚本。所以当在-bash下设置的变量,旨在-bash进程下有小,而-bash下的子进程bash是无效的,当export后再有效。
文件测试操作:
返回true,如果:
-e 文件存在
-a 文件存在(已被弃用)
-f 被测文件是一个regular文件(正常文件,非目录或设备)
-s 文件长度不为0
-d 被测对象是目录
-b 被测对象是块设备
-c 被测对象是字符设备
-p 被测对象是管道
-h 被测文件是符号连接
-L 被测文件是符号连接
-S(大写) 被测文件是一个socket
-t 关联到一个终端设备的文件描述符。用来检测脚本的stdin[-t0]或[-t1]是一个终端
-r 文件具有读权限,针对运行脚本的用户
-w 文件具有写权限,针对运行脚本的用户
-x 文件具有执行权限,针对运行脚本的用户
-u set-user-id(suid)标志到文件,即普通用户可以使用的root权限文件,通过chmod +s file实现
-k 设置粘贴位
-O 运行脚本的用户是文件的所有者
-G 文件的group-id和运行脚本的用户相同
-N 从文件最后被阅读到现在,是否被修改
f1 -nt f2 文件f1是否比f2新
f1 -ot f2 文件f1是否比f2旧
f1 -ef f2 文件f1和f2是否硬连接到同一个文件
二元比较操作符,比较变量或比较数字
整数比较:
-eq 等于 if [ "$a" -eq "$b" ]
-ne 不等于 if [ "$a" -ne "$b" ]
-gt 大于 if [ "$a" -gt "$b" ]
-ge 大于等于 if [ "$a" -ge "$b" ]
-lt 小于 if [ "$a" -lt "$b" ]
-le 小于等于 if [ "$a" -le "$b" ]
< 小于(需要双括号) (( "$a" < "$b" ))
<= 小于等于(...) (( "$a" <= "$b" ))
> 大于(...) (( "$a" > "$b" ))
>= 大于等于(...) (( "$a" >= "$b" ))
字符串比较:
= 等于 if [ "$a" = "$b" ]
== 与=等价
!= 不等于 if [ "$a" = "$b" ]
< 小于,在ASCII字母中的顺序:
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ] #需要对<进行转义
> 大于
-z 字符串为null,即长度为0
-n 字符串不为null,即长度不为0
注意:
使用-z或-n判断字符串变量时,必须要用""把变量引起来。
shell的特殊变量:
$$ [ shell固有的PID (ProcessID) ]
$- [ 使用Set命令设定的旗帜一览 ]
$? [ 最后运行的命令的结束代码(返回值) ]
$! [ shell 最后运行的后台进程的PID ]
$* [ 所有参数列表。如“$*”用“”“括起来的情况,以“$1 $2...$n”的形式输出所有参数。 ]
$@ [ 所有参数列表。如“$@”用“”括起来的情况,以“$1”“$2”...“$n”的形式输出所有参数 ]
$# [ 添加到壳的参数个数 ](参数总和)
$0 [ shell本身的文件名 ]
$1~$n [ $1是第一个参数,$2是第二个参数...。 ]
shell的命令:
ss -a | awk 'NR==2{print $2}'
NR==2 表示第二行
'{print $2}' 表示列数
ab -n 1000 -c 1000 http://ip/index.php 测试会话 1000 个请求
-n requests 在测试会话中所执行的请求总个数,默认一个
-c concurrency 一次产生的请求个数
shell的小命令:
block 数据块
ss -a 表示查询状态
ss -a|sort -nr排序(sort排序,-nr横排序)
ss -a|awk uniq 去重
ss -a|awk "{print $2}"|sort|uniq -c 第二列
ss -a|awk 'NR==1{print $2}'|sort 第一行第二列
ss -a|awk 'NR==4{print $2}'|sort|uniq -c
curl里面的一系列常见参数:
-A/ --user-agent <string> 设置用户代理发送给服务器
-b/ --cookie <name=string/file> cookie字符串或文件读取位置
-c/ --cookie-jar <file> 操作结束后把cookie写入到这个文件中
-C/ --continue-at <offset> 断点续传
-D/ --dump-header <file> 把header信息写入到该文件中
-e/ --referer 来源网址
-f/ --fail 连接失败时不显示http错误
-o/ --output 把输出写入到该文件中
-O/ --remote-name 把输出写到该文件中,保留远程文件的文件名
-r/ --range <range> 检索来自HTTP/1.1或FTP服务器字节范围
-s/ --silent 静音模式。不输出任何东西
-T/ --upload-file <file> 上传文件
-u/ --user <user[:password]> 设置服务器的用户和密码
-w/ --write-out [ format ] 什么输出完成后
-x/ --proxy <host[ :port ]> 在给定的端口上使用HTTP代理
-#/progress-bar 进度条显示当前的传送状态
curl http://www.baidu.com 测试服务器是否到达一个网站
curl http://www.baidu.com >> linux.html 使用linux的重定向保存
curl -o linux.html http://www.baidu.com 可以使用curl的内置option:-o保存网页
curl -O http://www.baidu.com/hell0.sh 可以使用curl的内置op tion:O(大写)保存网页中的文件,要注意这里后面的url要具体到某个文件,不然抓不下来
curl -o /dev/null -s -w %{http_code} www.linux.com 测试网页返回值 在脚本中,这是很常见的测试网站是否正常的用法
curl -x 192.168.100.100:1080 http://www.linux.com 很多时候需要用到代理服务器(比如事使用代理服务器上往或者因为使用curl别人网站而被别人屏蔽ip地址的时候),幸运的是curl通过使用内置option:-x来支持设置代理
curl -c cookiec.txt http://www.linux.com 保存http的response里面的cookie信息。重置option:-c (小写)执行后cookie信息就被存到了cookiec.txt里面了
curl -D cookied.txt http://www.linux.com 保存http的response里面的header信息。内置option:-D执行后cookie信息就被存到了cookied.txt里面了。注意:-c(小写)产生的cookie是不一样的。
curl -b cookiec.txt http://www.linux.com 很多网站都是通过监视你的cookie信息来判断你是否按规矩访问他们的网站的,因此我们需要使用保存的cookie信息。内置option:-b
curl -A "Mozila/4.0(compatible;MSIE 8.0;Windows NT 5.0)" http://www.linux.com 有些网站需要使用特定的浏览器去访问他们,有些还需要使用默写特定的版本。curl内置option:-A可以让我们指定浏览器去访问网站这样服务器端就会认为是使用IE8.0去访问的
curl -e "www.linux.com" http://mail.linux.com 很多服务器会检查http访问的referer从而来控制访问,比如:你是先访问首页,然后在访问首页中的邮箱页面,这里访问邮箱的referer地址就是访问首页成功后的页面地址,如果服务器发现对邮箱页面访问的referfer地址不是首页的地址,就断定了那个是盗链了curl中内置option:-e可以让我设定referfer,这样就会让服务器其以为你是从www.linux.com点击某个连接过来的
curl -O http://www.linux.com/{hello,bb}/dodo[1-5].JPG 下载重命名,由于下载的hello与bb中的文件都是dodo1,dodo2,dodo3,dodo4,dodo5。因此第二次下载的会把第一次的覆盖,这样就需要对文件进行重命名
curl -o #1_#2.JPG http://ww.linux.com/{hello,bb}/dodo[1-5].JPG这样在hello/dodo1.JPG的文件下载下来就hi变成hello_dodo1.JPG,其他文件一次类推,从而有效地避免了文件被覆盖。
通过位置变量创建 Linux 系统账户及密码:
shell脚本命令行发送email:
先安装sendemail
再编辑mail.rc的配置文件
保存退出重新启动你的mail
shell脚本定时:
再说shell定时运行时,首先说一下crontab的理解:
* * * * * 分 时 日 月 周
crontab有与官方的话语来说:crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,
并将其存放于“crontab”文件中,以供之后读取和执行。通常,crontab储存的指令被守护进程激活。crond常常在后台运行,每一分钟检查是否有预
定的作业需要执行。这类作业一般称为cron jobs。
crontab是:定时任务的守护进程,精确到分。
crontab的日志文件有: || /var/log/cron* 配置文件:vim /etc/crontab 进程:ps -ef|grep crond ==> /etc/init.d/crond restart
linux下的任何任务跳读分为两类,系统任务调度和用户任务调度。
系统任务调度:系统周期性索要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc/crontab文件,这个就是系统调度的被配置文件。
用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用crontab工具来时定制自己的计划任务。在crontab文件都被保存在/var/spool/cron目录中。其文件名玉用户名一致。
查看crontab的配置文件:
这里的前三行代表用crontab任务运行的环境变量
第一行shell变量指定了系统要用那个shell,这里是bash
第二行path变量指定了系统执行命令的路径
第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户
如果MAILTO变量的值为空,则表示不发送给任务执行信息给用户
[ 在我的配置文件里没有第四行:第四行的代码是:HOME=/ ,HOME变量指定了在执行命令或者脚本时使用的主目录。 ]
星号(*):代表所有可能的值,如month字段为星号,则表示在满足其他字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。
小结:
数字的表示最好用2 为阿拉伯数字显示
周和日最好的不要同时用
可以定向到日志文件或者空文件
定时任务一定是绝对路径,且目录必须存在才能出结果
crontab 服务一定要开启运行