一:清除/var/log/messages文件的简单脚本

版本一:

#root权限
cd /var/log
cat /dev/null>messages
echo "logs cleaned up"

脚本缺点

没有root执行不了

每一个步骤没有进行判断,只是命令的堆积,没有流程控制,没有逻辑

版本二

#!/bin/bash
LOG_DIR=/var/log
ROOT_UID=0
if["$UID" -ne "$ROOT_UID"]
then
    echo "Must be root to run this script"
    exit 1
fi
cd $LOG_DIR||{
    echo "cannot change to nesessary directory" >&2
    exit 1
}
cat /dev/null>messages && echo "logs cleaned up"
exit 0

清空日志的几种方法

  1. echo “”> filename.log

  2. echo>filename.log

  3. >filename.log

  4. cat /dev/null>filename.log


**************************总结*********************************************

shell的优势在于处理操作系统底层的业务,它有大量的命令作为支撑,2000多个命令,grep awk sed,一键安装,报警脚本,常规业务应用,shell更擅长

python的优点在于开发运维工具

查看当前shell:

echo $SHELL

grep root /etc/passwd


shell脚本以非交互的方式运行时,他会先查找环境变量ENV。该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当都去了ENV文件后,SHELL才开始执行

shell脚本中的内容

全局的环境变量:

/etc/profile

/etc/profile.d/

用户的环境变量:

~/.bashrc

~/.bash_profile

可以在创建出他们的shell及其派生出来的任意子进程shell中使用,环境变量应用于用户进程前,必须用export命令导出,环境变量是已经用内置命令export导出的变量

集中环境变量的创建方法:

  • export name=value

  • name=value; export name

  • declare -x name=value

显示环境变量:

env(printenv)或者是set

取消环境变量:

unset(临时生效),要永久生效,写在配置文件中。

本地环境变量:

在用户当前的shell生存期的脚本中使用,如果在shell重启动另一进程或者是退出,则本地变量失效。

变量使用小事例:


[root@uyhd000225 ~]# a=10.12.11.1
[root@uyhd000225 ~]# echo "a=$a"
a=10.12.11.1
[root@uyhd000225 ~]# b='10.12.11.1'
[root@uyhd000225 ~]# echo "b=$b"
b=10.12.11.1
[root@uyhd000225 ~]# c="10.12.11.1"
[root@uyhd000225 ~]# echo "c=$c"
c=10.12.11.1
[root@uyhd000225 ~]# echo "c=${c}"
c=10.12.11.1
[root@uyhd000225 ~]# a=10.12.11.1-$a
[root@uyhd000225 ~]# echo "a=$a"
a=10.12.11.1-10.12.11.1
[root@uyhd000225 ~]# b='10.12.11.1-$b'
[root@uyhd000225 ~]# echo "b=$b"
b=10.12.11.1-$b
[root@uyhd000225 ~]# c="10.12.11.1-$c"
[root@uyhd000225 ~]# echo "c=$c"
c=10.12.11.1-10.12.11.1
[root@uyhd000225 ~]#


单引号里面是啥就是啥,

习惯:数字不加引号;其他加双引号,特殊情况再考虑!!!!!!!awk与以上情况正好相反


shell编写规范,多模仿系统自带的函数库脚本/etc/init.d/function的定义思路


命令作为变量的使用方法:

使用反引号 如:time=`date +%F`(注意空格)

使用$()    如:time=$(date +%F)


shell的特殊变量:

  1. 位置变量

    1. $0获取当前执行的shell脚本的文件名,包括路径

    2. $n获取当前执行的shell脚本的第n个参数值。n取值为1到9;n为0表示脚本的文件名,如果n大于9,用大括号括起来${10}

    3. $*获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于“$1$2$3”

    4. $#获取当前shell命令行中参数的总个数

    5. $@这个程序的所有参数"$1","$2","$3"....这是将参数传递给其他程序的最佳方法,因为他会保留所有内嵌在参数中的任意空白

[root@uyhd000225 ~]# sh n.sh h a o
h a o
3
h a o
h a o
[root@uyhd000225 ~]# cat n.sh
echo $1 $2 $3
echo $#
echo $@
echo $*

$* 与 $@的区别:

  • $*:将所有命令行所有参数视为单个字符串 等同于“$1$2$3”.

  • $@;将所有命令行每个参数视为单独的字符串,等同于"$1","$2","$3";只是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白

  • $*,保存了以$IFS指定的分割符所分割的字符串组。
    $@,原样保存了参数列表,也就是"$1""$2"...


[root@uyhd000225 ~]# set "wo shi" fu wen chao
[root@uyhd000225 ~]# echo $#
4
[root@uyhd000225 ~]# for i in $*;do echo $i;done
wo
shi
fu
wen
chao
[root@uyhd000225 ~]# for i in $@;do echo $i;done
wo
shi
fu
wen
chao
[root@uyhd000225 ~]# for i in "$@";do echo $i;done
wo shi
fu
wen
chao
[root@uyhd000225 ~]# for i in "$*";do echo $i;done
wo shi fu wen chao
[root@uyhd000225 ~]# for i;do echo $i;done
wo shi
fu
wen
chao


2.  进程状态变量

   a.    $$获取当前shell进程的PID

   b.    $!执行上一个指令的PID

   c.    $?获取执行上一个指令的返回值(0为成功)

   d.    $_在此之前执行的命令或者脚本的最后一个参数

[root@uyhd000225 ~]# dirname /root/n.sh
/root
[root@uyhd000225 ~]# basename /root/n.sh
n.sh


shell编程基础(二)_root权限


shift命令:

shift会使位置参数发生改变,相当于武林神功斗转星移,你说厉害不厉害:$2变$1,$3变$2,.....在程序中没使用一次这种神功,所有的位置参数依次向左移动一个位置,并使$#减1,直到减到0为止!

[root@pacteralinux ~]# echo $@
JAVA_OPTS= -Xms32m -Xmx512m
[root@pacteralinux ~]# echo $#
3
[root@pacteralinux ~]# echo $1 $2 $3
JAVA_OPTS= -Xms32m -Xmx512m
[root@pacteralinux ~]# shift
[root@pacteralinux ~]# echo $1
-Xms32m
[root@pacteralinux ~]# echo $2
-Xmx512m
[root@pacteralinux ~]# echo $3
[root@pacteralinux ~]#


SHELL变量的子串应用:

  • ${#string} 返回string长度

[root@pacteralinux ~]# name=fuwenchao
[root@pacteralinux ~]# echo $name
fuwenchao
[root@pacteralinux ~]# echo {#name}
{#name}
[root@pacteralinux ~]# echo ${#name}
9
[root@pacteralinux ~]#
  • ${string:position}从position处开始提取string子串

    [root@pacteralinux ~]# echo ${name:2}
    wenchao
    #不包含第二个


  • ${string:Pos:Len}....................

    [root@pacteralinux ~]# echo ${name:2:3}
    wen
  • ${string#substring} 开头开始 删除最短匹配

    [root@pacteralinux ~]# echo ${name#wen}
    fuwenchao
  • ${string##substring} 开头开始 删除最长匹配


[root@pacteralinux ~]# echo ${name##wen}
fuwenchao
  • ${string%substring}    结尾开始   删除最短匹配


[root@pacteralinux ~]# name=fuwenchaofu
[root@pacteralinux ~]# echo ${name#fu}
wenchaofu
[root@pacteralinux ~]# echo $name
fuwenchaofu
[root@pacteralinux ~]# echo ${name%fu}
fuwenchao
[root@pacteralinux ~]#


  • ${string%%substring}    结尾开始   删除最长匹配

  • ${string/sub/replace}  替换

    [root@pacteralinux ~]# echo $name
    fuwenchaofu
    [root@pacteralinux ~]# echo ${name/wen/chao}
    fuchaochaofu
  • ${string/%sub/replace}  结尾开始替换

    [root@pacteralinux ~]# echo $name
    fuwenchaofu
    [root@pacteralinux ~]# echo ${name/wen/chao}
    fuchaochaofu
    [root@pacteralinux ~]# echo ${name/fu/chao}
    chaowenchaofu
    [root@pacteralinux ~]# echo ${name/%fu/chao}
    fuwenchaochao
    [root@pacteralinux ~]# echo ${name/#fu/chao}     #相当于不加#号
    chaowenchaofu
    [root@pacteralinux ~]#
  • ${value:=word}   若value未定义或者为空时,在返回word的同时赋值给value,不返回word的值

    [root@pacteralinux ~]# aaa=${bbb:=ccc}
    [root@pacteralinux ~]# echo $aaa
    ccc
    [root@pacteralinux ~]# bbb=123
    [root@pacteralinux ~]#
    [root@pacteralinux ~]# aaa=${bbb:=ccc}
    [root@pacteralinux ~]# echo $aaa
    123
    [root@pacteralinux ~]# ccc=123
    [root@pacteralinux ~]# aaa=${bbb:ccc}
    [root@pacteralinux ~]# echo $aaa
    [root@pacteralinux ~]# aaa=${bbb:=ccc}
    [root@pacteralinux ~]# echo $aaa
    123
    [root@pacteralinux ~]# echo $bbb
    123
    [root@pacteralinux ~]#
    [root@uyhd000225 test]# echo $fuw
    [root@uyhd000225 test]# fuw=en
    [root@uyhd000225 test]# echo $fuw
    en
    [root@uyhd000225 test]# resu=${test3:=fuw}
    [root@uyhd000225 test]# echo $resu
    fuw
    [root@uyhd000225 test]# echo $test3
    fuw
    [root@uyhd000225 test]#


  • ${value:?message} 若value已赋值的话,正常替换,否则将消息message输出到标准错误输出(若此替换出现在shell程序中,那么该程序将终止运行

    [root@uyhd000225 test]# result1=${wenchaofu:?"not define haah"}
    -bash: wenchaofu: not define haah
    [root@uyhd000225 test]# echo $result1
    [root@uyhd000225 test]# ${wenchaofu:?"not define haah"}
    -bash: wenchaofu: not define haah



  • ${value:-word}   若value未定义或者为空时,返回word字符串,而不是word的值!可以用来判断变量是否没有定义!去掉冒号效果一样!

    • (应用:rm -rf ${$path-/tmp/})

    • find ${path-/tmp/} -name "*.tar.gz" type f |xargs rm -f

  • [root@uyhd000225 test]# echo $test
    [root@uyhd000225 test]# result=${test:-unset}
    [root@uyhd000225 test]# echo $test
    [root@uyhd000225 test]# echo $result
    unset
    [root@uyhd000225 test]#

  这种用法在yum install httpd安装的/etc/init.d/httpd脚本中以及/etc/init.d/crond脚本中都可以看到    

[root@uyhd000225 test]# echo $test
[root@uyhd000225 test]# UN=123
[root@uyhd000225 test]# re=${test:-UN}
[root@uyhd000225 test]# echo $test
[root@uyhd000225 test]# echo $UN
123
[root@uyhd000225 test]# echo $re
UN
[root@uyhd000225 test]#
  • ${value:+word}   若value已经定义,返回word;他用来测设变量是否存在!

    [root@uyhd000225 test]# wenchaofu=123
    [root@uyhd000225 test]# echo $wenchaofu
    123
    [root@uyhd000225 test]# result1=${wenchaofu:+"not define"}
    [root@uyhd000225 test]# echo $result1
    not define
    [root@uyhd000225 test]#







shell脚本的执行可以采用一下三种方式:

  1. bash script-name 或者是 sh script-name(推荐)

  2. path/script-name 或者是 ./script-name

  3. source script-name 或者是 . script-name (.执行可以将“子shell”中的变量的值或者函数的返回值传递给当前的“父shell”脚本中使用,而不是产生一个子shell来执行命令文件中的命令)(我的理解其实就是在一个进程中共享相同的环境变量)


区别:

Last login: Mon Dec  9 14:27:28 2013 from 182.151.205.254
[root@uyhd000225 ~]# echo 'userdir=`pwd`'>pwd.sh
[root@uyhd000225 ~]# cat pwd.sh
userdir=`pwd`
[root@uyhd000225 ~]# sh pwd.sh
[root@uyhd000225 ~]# echo $userdir
[root@uyhd000225 ~]# . pwd.sh
[root@uyhd000225 ~]# echo $userdir
/root
[root@uyhd000225 ~]#

解释:当前的窗口是一个shell,脚本是另外一个shell,执行sh脚本的时候把userdir定义了,但不会把这个变量的定义传递到当前的shell命令行来,但是用.号加载

可以把里面的变量传递到当前的shell!

[root@uyhd000225 test]# wen=chao
[root@uyhd000225 test]# echo $wen
chao
[root@uyhd000225 test]# echo "echo $wen"
echo chao
[root@uyhd000225 test]# echo 'echo $wen'
echo $wen
[root@uyhd000225 test]# echo 'echo $wen'>son.sh
[root@uyhd000225 test]# cat son.sh
echo $wen
[root@uyhd000225 test]# sh son.sh
[root@uyhd000225 test]# echo $wen
chao
[root@uyhd000225 test]# echo $SHELL
/bin/bash
[root@uyhd000225 test]# echo 'echo $SHELL'>son.sh
[root@uyhd000225 test]# cat son.sh
echo $SHELL
[root@uyhd000225 test]# sh son.sh
/bin/bash
[root@uyhd000225 test]#

shell脚本编写规饭

  • 开头指定脚本解释器

   #!/bin/bash

  • 接着加上版本版权信息

   #Date XXXXX

   #Author Created by wenchao

   #Mail pianzif@126.com

   #Function this script is written to........s

   #Version 1.1

   可以配置vim编辑器的配置文件~/.vimrc使他自动加上版权信息

  • 脚本中不用中文注释

  • 扩展名以.sh

  • 优秀的代码书写习惯

    • 成对书写,括号,引号...

    • []两端要有空格[ asd ]

    • 流程控制语句一次书写完成。


if 条件
     then
        内容
fi



for n in list
do
    content
done
    • 缩进让代码更易读