早些时候的shell笔记

39次阅读

共计 10775 个字符,预计需要花费 27 分钟才能阅读完成。

一、shell 简介

 1. 常见的 shell
      bash: linux 标准 shell
      sh: 早起 shell
      csh: ksh tcsh Unix shell
      vi: /etc/shells linux 支持的 shell
 2. 编写运行
      #!/bin/bash
      echo "helloworld!"
      wq hello.sh
      chmod 755 ./hello.sh
      ./hello.sh
 3. 常见命令
      1). 历史命令 history
           /etc/profile 是 linux 的环境变量文件。注销才能使改变生效
           HISTSIZE 属性指示可以保存的历史记录条数
           历史命令保存在~/.bash_history
           history -w 把内存中的命令保存到文件
           history -c 清空历史命令
           !+ 历史命令的行号 执行该条命令
           !+ 字符串 执行以该字符串开头的最近执行的历史命令
      2). 别名 alias
           alias ls='ls --color=never'     手工设定别名
           ~/bashrc 是 linux 的环境变量文件,其中可以配置命令别名
 4. 输入输出重定向
      标准输入          /dev/stdin     0                    键盘
      标准输出          /dev/stdout     1                    显示器
      标准错误输出     /dev/stderr     2                    显示器
                          #设备文件名     #文件描述          #默认设备
      1). 输出重定向
      > 覆盖     ls > aa
      >> 追加     ls >> aa
      ls zzzzz 2>>aa          错误信息输出到 aa(注意:错误输出不能有空格)ls zzzzz &>aa               正确和错误的信息都输出到 aa(注意:只能覆盖不能追加)ls zzzzz >>aa 2>>bb     正确的信息输出到 aa,错误的信息输出到 bb
      ls zzzzz >>a 2>&1          错误和正确信息都输出到 aa,可以追加
                2>&1          把标准错误重定向到标准正确输出
      2). 多命令的顺序执行
      命令 1; 命令 2; 命令 3;          命令 1、2、3 顺序依次执行,之间没有任何关系
      命令 1 && 命令 2               命令 1 正确执行后命令 2 才会执行
      命令 1 || 命令 2               命令 1 不正确执行命令 2 才会执行
      ls && echo "yes" || ehco "no"          可以做简单的条件测试
      命令 1 | 命令 2                    命令 1 的执行结果作为命令 2 的执行条件或者操作对象。没有输出的命令不能作为第一条命令
      netstat -tlun | grep 80     该命令用于查看端口是否开启
                                    netstat -tlun 查看端口监听状态,grep 80 提取其中有 80 字样的内容。(管道符:将前者的结果作为后者的操作对象)

二、变量

 1. 分类:本地变量、环境变量、位置参数变量、预定义变量
 2. 本地变量
      1). 声明          aa=123
      2). 调用          echo $aa
      3). 查看变量     set
      4). 删除变量     unset 变量名
 3. 主要设定规则
      1). 变量值中有空格,用引号包围
      2).""包裹的内容中如果有特殊字符,如 $ 会被识别出来。aa="hello world"; echo“$aa"; 输出 hello world。一般不用来 "" 包裹特殊字符
      3).'' 包裹的所有内容都看成普通字符
      4). 变量值可以直接调用系统命令(只是将命令的结果赋给变量)。` 命令 `(反引号)或者 $(命令)          cc=$(ls -l /root); echo $cc 或者 cc=`ls -l /root`; echo $cc
      5). 变量值可以累加。aa=123; aa="$aa"456; echo $aa;          会输出 123456
      6). 环境变量大写
 4. 环境变量
      1). 声明
           export 变量名 = 变量值
           export 变量名
      2). 查看
      set               查看所有变量
      env、export     只查看环境变量
      declare          声明变量类型的,如果不特别声明,所有变量为字符串类型
           -i     声明为 int 型
           -x     声明为环境变量
      PATH     环境遍历路径。PATH="$PATH":/root/sh     可以追加 /root/sh 到 PATH 中
 5. 环境变量配置文件
      /etc/profile
      /etc/bashrc          所有用户生效
      ~/.bashrc
      ~/.bash_profile          只对指定用户生效
 6. 位置参数变量
      $0     命令自己本身
      $1     第一个参数
      ...
      $9     第 9 个参数
 7. 预定义变量
      $?     只要 $? 不为零说明上一句语句没有正确执行
      #!/bin/bash
      echo "canshugeshu: $#"          $# 输出参数个数
      echo "canshuzhi: $*"          $* 输出所有参数值
      echo "shifouzhengchagn: $?"     $? 不为零说明上一句语句没有正确执行
 8. 键盘读取命令
      #!/bin/bash
      read -p "input the 1st num:" -t 10 num1     -t 等待时间 -p 按行读
      read -p "input the 2nd num:" -t 10 num2
      sum=$(($num1+$num2))
      echo "sum is $sum"
 9. 变量值默认都是字符串型,要进行运算有三种方法:1).declare
           num1=123
           num2=345
           declare -i sum=$num1+$num2
      2).sum=$(($num1 + $num2))
      3).sum=$(expr $num1 + $num2)     注意:+ 左右必须有空格
      4). 运算符     + - * / %

三、shell 中常用的命令

 1. 行提取命令 grep(在文档当中匹配行)
      grep "hello" test.txt
      grep -v "hello" test.txt     -v 反向选择。把不包含 hello 的行选出来
                          -n 提取时,显示行号
      匹配正则表达式举例:grep "[^a-z]hen" test_rule.txt     该表达式匹配 ` 非小写字母 `+hen 的行     [] 代表一个字母     [^] 表示取反
           grep "\.$" test_rule.txt     该表达式匹配 以点结尾的行     . 代表任意一个字符,加了转义符 \ 后只仅仅代表点     $ 代表行的结尾
           grep "^[^A-Za-Z]" test_rule.txt          匹配 不以字母开头的行     ^ 在中括号外表示行开头
           grep "^$"                    匹配 空行,即回车行
           grep "oo*"                    匹配 有 o 的行          * 匹配前一个字母出现一次到任意多次
 2. 列提取命令
      1).cut     cut -d "分隔符" -f 列号 文件     (缺点:对空格匹配不好)
           cut -d ":" -f 1,3 /etc/passwd     提取 linux 系统的用户名及其 UID
           cat /etc/passwd | grep "/bin/bash" | cut -d ":" -f 1,3          提取可登陆的用户(其 bash 在 /bin/bash 下)2).awk
           last     系统登陆日志
           last | grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | awk '{printf $1"\t"$3"\n"}'
                提取远程登陆的用户和登陆 ip(提取有 ip 的行,在行中提取第一列和第三列)其中:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} 匹配 IP 地址
                     printf 代表格式化输出     \t 制表符     \n 换行符     \r 回车
 3.echo
      -e 识别格式化打印内容
      echo -e "1\t2\t3" 识别制表符打印
      echo -e "\e[1;31m this is colorful content\e[0m"
           \e[     两个这个之间包裹要带色打印的内容
           1;31m     代表按什么颜色打印或者背景颜色是什么
                字体颜色:30m= 黑色,31m= 红色,32m= 绿色,33m= 黄色,34m= 蓝色,35m= 洋红色,36m= 青色,37m= 白色
                背景颜色:40m= 黑色,41m= 红色,42m= 绿色,43m= 黄色,44m= 蓝色,45m= 洋红色,46m= 青色,47m= 白色
           0m     代表恢复颜色(重置)cat -A test.txt     显示隐藏字符,包括换行符(类 Unix 中换行符是 $,dos 中是 ^M$)取消 dos 文档的回车符,两种办法:1).dos2unix 文档路径
           2).vi -b 文档路径     :%s/^M//g     (^M 用 ctrl+v+ M 输入)

四、条件测试语句

 1. 测试文件类型
      test -e 文件路径 或 [-e 文件路径](注意:[] 中必须有空格 )     测试文件是否存在
      test -f 文件路径                              测试文件是否普通文件
      test -d 文件路径                              测试文件是否目录
      test -b 文件路径                              测试文件是否块设备文件
      test -c 文件路径                              测试文件是否字符设备文件
           test -e /etc/hello.sh && echo "yes" || echo "no"
           [-e /etc/hello.sh] && echo "yes" || echo "no"
 2. 测试文件权限
      test -r 文件路径     测试是否有可读权限
      test -w 文件路径     测试是否有可写权限
      test -x 文件路径     测试是否有执行权限
      test -s 文件路径     测试文件是否非空文件
 3. 两个文档比较
      [file1 -nt file2]     测试是否 file1 比 file2 新
      [file1 -ot file2]     测试是否 file1 比 file2 旧
      [file1 -ef file2]     测试是否 file1 和 file2 是链接文件
           [test1.txt -nt test2.txt] && echo "yes" || echo "no"
 4. 两个数值之间判断
      [n1 -eq n2]     equal
      [n1 -nt n2]     not equal
      [n1 -gt n2]     greate than
      [n1 -lt n2]     little than
      [n1 -ge n2]     greate equal
      [n1 -le n2]     little equal
 5. 判断字符串
      [-z 字符串]          测试字符串是否为空
      [字符串 1 == 字符串 2]     测试字符串是否相等
      [字符串 1 == 字符串 2]     测试字符串是否相等
      [字符串 1 != 字符串 2]     测试字符串是否不等
 6. 逻辑判断
      a     逻辑与
           [-z $file -a -e $file] && echo "yes" || echo "no"
      o     逻辑或
      !     逻辑非 

五、流程控制

 1.if 语句
      1).if ... then ... fi
           例:如果 /boot 分区使用超过 80% 则报警
           #!/bin/bash
           RATE=$(df -hT | grep "/boot" | awk '{printf $6"\n"}' | cut -d "%" -f 1)
           if [$RATE -gt 85]
           then
                echo -e "\e[1;31mthe /boot is nearly full\e[0m"
           fi
           #df -hT     df 文件系统占用情况     -h human readable     -T print file system type
      2).if ... then ... else ... fi
           例:如果 Apache 服务没启动就启动它
           #!/bin/bash
           httpd=`netstat -tlun | awk '{printf $4"\n"}' | grep ":80"`
           #httpd=`ps aux | grep "httpd" | grep -v "grep"`
           if [-z "$httpd"]
           then
                echo -e "\e[1;31mhello\e[0m"
                /etc/rc.d/init.d/httpd start
           else
                echo -e "\e[1;31mhttpd is running\e[0m"
           fi
           #ps aux     显示终端所有进程
      3).if ... then ... elif ... then ... else ...
 2.for 语句
      1).for ... in ... do ... done
           例:输入目录名打印出目录下的文件名
           #!/bin/bash
           read -p "input the filepath:" -t 10 path
           if [-z "$path"]
           then
           echo -e "\e[1;31minput a non-void path\e[0m"
                exit 1
           elif [! -e "$path"]
           then
                echo -e "\e[1;31mthe file path is not avaliable\e[0m"
                exit 2
           else
                files=`ls $path`
                echo $files
                for i in $files
                do
                     echo $i
                done
           fi
      2).for ... in ... do ... done
           例:1-100 累加
           #!/bin/bash
           s=0
           for ((i=1;i<=100;i=i+1))
           do
                s=$(($s + $i))
           done
           echo $s
 3.while ... do ... done
      例:实现批量添加用户
      #!/bin/bash
      i=1
      while [$i -le 20]
      do
           useradd user_$i
           echo "123456" | passwd --stdin user_$i &> /etc/null
           echo "---user_$i is created---"
           i=`expr $i + 1`
      done
      例:实现批量删除用户
      #!/bin/bash
      users=`cat /etc/passwd | grep "/bin/bash" | cut -d ":" -f 1 | grep "^user_"`
      for i in $users
      do
          userdel -r $i
          echo "---$i is deleted---"
      done
 4.case 多重分支语句
      例:打印选择列表,输出选择
      #!/bin/bash
      echo -e "shanghai->1\n"
      echo -e "beijing->2\n"
      echo -e "lanzhou->3\n"
      read -p "input the num of your choice:" -t 10 choice
      case $choice in
          "1")
           echo -e "\e[1;31mshanghai\e[0m"
           ;;
          "2")
           echo -e "\e[1;31mbeijing\e[0m"
           ;;
          "3")
           echo -e "\e[1;31mlanzhou\e[0m"
           ;;
          *)
           echo -e "\e[1;33minput the avaliable num\e[0m"
      esac

六、Apache 启动脚本分析(/etc/rc.d/init.d/httpd)

 #!/bin/bash
 #
 # httpd        Startup script for the Apache HTTP Server
 #
 # chkconfig: - 85 15
 # description: Apache is a World Wide Web server.  It is used to serve \
 #              HTML files and CGI.
 # processname: httpd
 # config: /etc/httpd/conf/httpd.conf
 # config: /etc/sysconfig/httpd
 # pidfile: /var/run/httpd.pid
 # Source function library.
 . /etc/rc.d/init.d/functions
 if [-f /etc/sysconfig/httpd]; then
      . /etc/sysconfig/httpd
 fi
 # Start httpd in the C locale by default.
 HTTPD_LANG=${HTTPD_LANG-"C"}
 # This will prevent initlog from swallowing up a pass-phrase prompt if
 # mod_ssl needs a pass-phrase from the user.
 INITLOG_ARGS=""
 # Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
 # with the thread-based "worker" MPM; BE WARNED that some modules may not
 # work correctly with a thread-based MPM; notably PHP will refuse to start.
 # Path to the apachectl script, server binary, and short-form for messages.
 apachectl=/usr/sbin/apachectl
 httpd=${HTTPD-/usr/sbin/httpd}
 prog=httpd
 pidfile=${PIDFILE-/var/run/httpd.pid}
 lockfile=${LOCKFILE-/var/lock/subsys/httpd}
 RETVAL=0
 # check for 1.3 configuration
 check13 () {
      CONFFILE=/etc/httpd/conf/httpd.conf
      GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
      GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
      GONE="${GONE}AccessConfig|ResourceConfig)"
      if LANG=C grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
           echo
           echo 1>&2 "Apache 1.3 configuration directives found"
           echo 1>&2 "please read /usr/share/doc/httpd-2.2.3/migration.html"
           failure "Apache 1.3 config directives test"
           echo
           exit 1
      fi
 }
 # The semantics of these two functions differ from the way apachectl does
 # things -- attempting to start while running is a failure, and shutdown
 # when not running is also a failure.  So we just do it the way init scripts
 # are expected to behave here.
 start() {
      echo -n $"Starting $prog:"
      check13 || exit 1
      LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
      RETVAL=$?
      echo
      [$RETVAL = 0] && touch ${lockfile}
      return $RETVAL
 }
 # When stopping httpd a delay of >10 second is required before SIGKILLing the
 # httpd parent; this gives enough time for the httpd parent to SIGKILL any
 # errant children.
 stop() {
      echo -n $"Stopping $prog:"
      killproc -p ${pidfile} -d 10 $httpd
      RETVAL=$?
      echo
      [$RETVAL = 0] && rm -f ${lockfile} ${pidfile}
 }
 reload() {
     echo -n $"Reloading $prog:"
     if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
      RETVAL=$?
      echo $"not reloading due to configuration syntax error"
      failure $"not reloading $httpd due to configuration syntax error"
     else
      killproc -p ${pidfile} $httpd -HUP
      RETVAL=$?
     fi
     echo
 }
 # See how we were called.
 case "$1" in
   start)
      start
      ;;
   stop)
      stop
      ;;
   status)
      status -p ${pidfile} $httpd
      RETVAL=$?
      ;;
   restart)
      stop
      start
      ;;
   condrestart)
      if [-f ${pidfile} ] ; then
           stop
           start
      fi
      ;;
   reload)
      reload
      ;;
   graceful|help|configtest|fullstatus)
      $apachectl $@
      RETVAL=$?
      ;;
   *)
      echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
      exit 1
 esac
 exit $RETVAL
 #!/bin/bash
 #
 # httpd        Startup script for the Apache HTTP Server
 #
 # chkconfig: - 85 15
 # description: Apache is a World Wide Web server.  It is used to serve \
 #              HTML files and CGI.
 # processname: httpd
 # config: /etc/httpd/conf/httpd.conf
 # config: /etc/sysconfig/httpd
 # pidfile: /var/run/httpd.pid
 # Source function library.
 . /etc/rc.d/init.d/functions
 if [-f /etc/sysconfig/httpd]; then
      . /etc/sysconfig/httpd
 fi
 # Start httpd in the C locale by default.
 HTTPD_LANG=${HTTPD_LANG-"C"}
 # This will prevent initlog from swallowing up a pass-phrase prompt if
 # mod_ssl needs a pass-phrase from the user.
 INITLOG_ARGS=""
 # Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
 # with the thread-based "worker" MPM; BE WARNED that some modules may not
 # work correctly with a thread-based MPM; notably PHP will refuse to start.
 # Path to the apachectl script, server binary, and short-form for messages.
 apachectl=/usr/sbin/apachectl
 httpd=${HTTPD-/usr/sbin/httpd}
 prog=httpd
 pidfile=${PIDFILE-/var/run/httpd.pid}
 lockfile=${LOCKFILE-/var/lock/subsys/httpd}
 RETVAL=0
 # check for 1.3 configuration
 check13 () {
      CONFFILE=/etc/httpd/conf/httpd.conf
      GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
      GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
      GONE="${GONE}AccessConfig|ResourceConfig)"
      if LANG=C grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
           echo
           echo 1>&2 "Apache 1.3 configuration directives found"
           echo 1>&2 "please read /usr/share/doc/httpd-2.2.3/migration.html"
           failure "Apache 1.3 config directives test"
           echo
           exit 1
      fi
 }
 # The semantics of these two functions differ from the way apachectl does
 # things -- attempting to start while running is a failure, and shutdown
 # when not running is also a failure.  So we just do it the way init scripts
 # are expected to behave here.
 start() {
      echo -n $"Starting $prog:"
      check13 || exit 1
      LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
      RETVAL=$?
      echo
      [$RETVAL = 0] && touch ${lockfile}
      return $RETVAL
 }
 # When stopping httpd a delay of >10 second is required before SIGKILLing the
 # httpd parent; this gives enough time for the httpd parent to SIGKILL any
 # errant children.
 stop() {
      echo -n $"Stopping $prog:"
      killproc -p ${pidfile} -d 10 $httpd
      RETVAL=$?
      echo
      [$RETVAL = 0] && rm -f ${lockfile} ${pidfile}
 }
 reload() {
     echo -n $"Reloading $prog:"
     if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
      RETVAL=$?
      echo $"not reloading due to configuration syntax error"
      failure $"not reloading $httpd due to configuration syntax error"
     else
      killproc -p ${pidfile} $httpd -HUP
      RETVAL=$?
     fi
     echo
 }
 # See how we were called.
 case "$1" in
   start)
      start
      ;;
   stop)
      stop
      ;;
   status)
      status -p ${pidfile} $httpd
      RETVAL=$?
      ;;
   restart)
      stop
      start
      ;;
   condrestart)
      if [-f ${pidfile} ] ; then
           stop
           start
      fi
      ;;
   reload)
      reload
      ;;
   graceful|help|configtest|fullstatus)
      $apachectl $@
      RETVAL=$?
      ;;
   *)
      echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
      exit 1
 esac
 exit $RETVAL




============================================================================================================

 pstree                         查询进程树
 more                         分屏显示文件内容
 netstat -tlun | greap 80     #netstat -tlun 系统中启动的所有端口
 date "+%F %T"     #2015-01-16 12:30:39
 yum install -y sysstat

正文完
 0