一:清除/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
清空日志的几种方法
echo “”> filename.log
echo>filename.log
>filename.log
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的特殊变量:
位置变量
$0获取当前执行的shell脚本的文件名,包括路径
$n获取当前执行的shell脚本的第n个参数值。n取值为1到9;n为0表示脚本的文件名,如果n大于9,用大括号括起来${10}
$*获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于“$1$2$3”
$#获取当前shell命令行中参数的总个数
$@这个程序的所有参数"$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
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脚本的执行可以采用一下三种方式:
bash script-name 或者是 sh script-name(推荐)
path/script-name 或者是 ./script-name
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
缩进让代码更易读