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 服务一定要开启运行

 

 

 

  

posted @ 2020-01-03 21:16  h0001  阅读(413)  评论(0编辑  收藏  举报