Shell是一个命令解释器,它在操做系统的最外层,负责直接与用户对话,把用户的html
输入解释给操做系统.井处理各类各样的操做系统的输出结果,输出屏幕返回给用户python
这种对话方式能够是linux
交互的方式:从键盘输入命令,经过/bin/bash的解折,能够当即获得shell的回应redis
非交互的方式:脚本shell
Shell执行命令分为两种方式编程
内置命令:如讲过的cd ,pwd, exit和echo等命令.当用户登陆系统后,shell以及内置命令就被系统载入到内存,而且一直运行vim
通常命令:如15,磁盘上的程序文件==>调入内存==>执行命令bash
当linux命令或语句不在命令行下执行(严格说,命令行也是Shell),而是经过一个程序文件执行时,该程序就被称为Shell脚本或Shell程序。less
用户能够在Shell脚本中敲入一系列的命令及命令语句组合。这些命令、变量和流程控制语句等有机的结合起来就造成一个功能强大的Shell脚本。运维
日志文件在哪?
用什么命令能够清空文件
写一个简单的shell脚本。
怎样执行脚本?
进阶:
有没有考虑到
1)有没有脚本放在统一的目录
2)权限:用哪一个用户执行文件
3)清空错文件怎么办,该怎么办
4)错误提示:有没有成功知不知道
5)脚本通用性
[root@ccdata]# mkdir -p /server/scripts
[root@ccdata]# cd /server/scripts
[root@ccscripts]# vim clear_log.sh
#!/bin/bash
cd /var/log/
>messages
~
[root@ccscripts]# cat clear_log.sh
#!/bin/bash
cd /var/log/
>messages
[root@ccscripts]# sh clear_log.sh
[root@ccscripts]# cat /var/log/messages #空的清空了
[root@cc~ ]#mkdir -p/server/scripts #要有规范的存放脚本目录
[root@cc ~]# cd/server/scripts/
[root@ cc scripts]# vim clear_log.sh
#!/bin/bash
LOG_DIR=/var/log
ROOT_UID=O #UID为0时,用户才具备root权限echo $UID
#要使用root用户执行
if[ "$UID" -ne "$ROOT _UID" ]
then
echo"Must be root to run this script."
exit 1
fi
#||表示前面执行失败则执行后面,区别于&&
cd $ LOG_DIR 2>/dev/null || {
echo"Cannot change to necessary directory.”
exit 1
}
cat /dev/null>messages && echo"Logs cleaned up."
exit 0
#退出以前返回0表示成功,返回1表示失败。
echo >test.log
>test.log
cat /dev /null >test.log
#清空内容。保留文件
Shell就是命令解释器.==>翻译官
Shell脚本==>命令放在脚本里
Shell脚本擅长处理纯文本类型的数据,而linux中几乎全部的配置文件、日志文件等都是纯文本类型文件
推荐使用vim编辑器
规范的Shell脚本第一行会指出由哪一个程序(解释器)来执行脚本中的内容。在linux bash编程中通常为,
#!/bin/bash
或
#!/bin/sh<==255个字符之内
其中开头的“#!”又称为幻数,在执行Shell脚本的时候,内核会根据“#!”后的解释器来肯定用0个程序解释脚本中的内容。
注意:这一行必须在每一个脚本顶端的第一行,若是不是第一行则为脚本注释行
[root@cc~]# bash --version
GNU bash, version 4.1.2(1)-release(x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software; you are free to change andredistribute it.
There is NO WARRANTY, to the extent permitted bylaw.
1.4 bash漏洞(破壳漏洞)
若是是比较老的系统,须要注意shell的版本过低,有漏洞,须要升级shell。
#验证方法
[root@cc~]# env x='() { :;}; echo be careful' bash -c "echo this is a test"
this is a test
若是返回2行
be careful 就是有漏洞须要升级
#升级方法 yum -y update bash
#!/bin/bash
#!/usr/bin/awk
#!/bin/sed
#!/usr/bin/tcl
#!/usr/bin/per
#!/usr/bin/env python
若是脚本开头不指定解释雄,就要用对应的解释器执行脚本。例如bash test.h和python test.py。
在Shell脚本中,跟在#后面的内容表示注释。注释部分不会被执行,仅给人看。注释能够自成一行,也能够跟在命令后面,与命令同行。要养成写注释的习惯,方便本身与他人。
最好不用中文注释,由于在不一样字符集的系统会出现乱码
1. bash script-name 或sh script-name(推荐使用)
这种方法是当脚本自己没有可执行权限时常使用的方法
path/script-name或./script-name(全路径或当前路径执行脚本)
这种方法首先须要给脚本文件可执行权限。
source script-name或. script-name注意点号,且点号后有空格。
sh<script-name或cat script-name |sh或cat script-name |bash
开头指定脚本解释器。
开头加版本版权等信息,可配置~/.vimrc文件自动添加。
脚本不要用中文注释,尽可能用英文注释
脚本以.sh为扩展名。
放在统一的目录
代码书写优秀习惯
a. 成对的内容一次性写出来,防止遗漏,如[ ]、' '、" "等
b. []两端要有空格,先输入[],退格,输入2个空格,再退格写。
c. 流程控制语句一次书写完,再添加内容。
if条件
then
内容
fi
d. 经过缩进让代码易读。
e. 脚本中的引号都是英文状态下的引号,其余字符也是英文状态。
好的习惯可让咱们避免不少没必要要的麻烦,提升工做效率
变量就是用一个固定的字符串(也多是字符数字等的组合),替代更多史复杂的内这个内容里可能还会包含变量和路径,字符串等其余内容。变量的定义是存在内存容中。
变量分为两类:
环境变量(也可称为全局变量) :能够在建立他们的Shell及其派生出来的子Shell中使用。环境变量又能够分为自定义环境变量和bash内置的环境变量。
局部变量(普通变量):只能在建立他们的Shell函数或shell脚本中使用,还记得前而的$user?咱们建立的通常都是普通变量。
环搅变量用于定义Shell的运行环境,保证Shell命令的正确执行,Shell经过环境变量来肯定登陆用户名、命令路径、终端类型、登陆目录等,全部的环境变量都是全局变量,可用于全部子进程中,包括编辑器、shell脚本和各种应用。但crond计划任务除外,还须要从新定义环境变量。
环倍变量能够在命令行中设置,但用户退出时这些变量值也会丢失,所以最好在用户家目录下的bash_profile文件中或全局配$/etc/bashrc, /etc/profile文件或者/etc/profile.d/目录中定义。将环境变量放入profile文件中,每次用户登陆时这些变量值都将被初始化。
一般,全部环境变量都为大写。环境变量应用于用户进程前,都应该用export命令导出。例如-exportOLDBOV=1。
有一些环境变量,好比HOME, PATH, SHELL, UID,USER等,在用户登陆以前就已经被/bin/loein程序设置好了。一般环境变量定义并保存在用户家目录下的.bash profile或/etc/profile 文件中。
[root@cc ~]# echo $HOME
/root
[root@cc ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@cc ~]# echo $SHELL
/bin/bash
[root@cc ~]# echo $UID
0
[root@cc ~]# echo $USER
root
[root@cc~]# env查看系统环境变量
HOSTNAME=cc
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.106.1 49474 22
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
CVS_RSH=ssh
SSH_CONNECTION=192.168.106.1 49474 192.168.106.13222
LESSOPEN=||/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[root@cc~]# echo $PS1
[\u@\h \W]\$
局部变量在用户当前的shell生存期的脚本中使用。例如,局部变量OLDBOy取值为ett098,这个值只在用户当前shell生存期中有意义。若是在shell中启动另外一个进程或退出,局部变量OLDBOY值将无效。
变量名=value
变量='value '
变量名="value"
通常是字母、数字、下划线组成,且以字母开头。如oldboy,oldboy123,
oldboy_training。变量的内容,可使用单引号或双引号引发来,或不加引号。
[root@cc ~]#a=192.168.1.2
[root@cc ~]# echo"a=$a"
a=192.168.1.2
[root@cc ~]#b='192.168.1.2'
[root@cc ~]#c="192.168.1.2"
[root@cc ~]# echo"b=$b"
b=192.168.1.2
[root@cc ~]# echo"c=$c"
c=192.168.1.2
[root@cc ~]# DATE=`date +%F`
[root@cc ~]# echo $DATE
2017-02-17
CMD=`ls`的ls两侧的符号是键盘tab键上面的,不是单引号
在变量名前加$,能够取得此变量的值,使用echo或printf命令能够显示变量的值,$A和${A}写法不一样,效果同样,推荐后面的写法
${WEEK}DAY若变量和其余字符组成新的变量就必须给变量加上大括号{}。
养成将全部字符串变量用双引号括起来使用的习惯,减小编程遇到的怪异错误。"$A"和"${A}"
变量名只能由字母、数字、下划线组成,且以字母开头。
规范的变量名写法定义:见名知意
1)OldboyAge=1 <==每一个单词首字母大写
2)oldboy_age=1<==每一个单词之间用“_”
3)oldboyAgeSex=1 <==驼峰语法: 首个单词字母小写,其他单词首字母大写
3. =号的知识,a=1中的等号是赋值的意思,比较是否是和等为"=="
4. 打印变量,变量名前接$符号,变量名后紧接字符的时候,要用大括号括起来
注意变量内容引用方法,通常为双引号,简单连续字符能够不加引号,但愿原样输出,使用单引号。
变里内容是命令要用反引号` `或者$( )把变量括起来使用。
$0 获取当前执行的shell脚本的文件名,若是执行脚本带路径那么就包括脚本路径。
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,若是n大于9用大括号括起来{10},参数以空格隔开。
$# 获取当前执行的shell脚本后面接的参数的总个数
[root@cc scripts]# vim teshu.sh
[root@cc scripts]# cat teshu.sh
#! /bin/bash
echo $0
[root@ccscripts]# sh teshu.sh
teshu.sh
[root@ccscripts]# sh /server/scripts/teshu.sh
/server/scripts/teshu.sh
[root@cc scripts]# cat teshu.sh
#! /bin/bash
echo $0
echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 #写法是错误的
[root@cc scripts]# sh teshu.sh
teshu.sh
0 1 2 3 4 5 #显示的是标为红色的部分
[root@cc scripts]# cat teshu.sh
#! /bin/bash
echo $0
echo$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} #正确的写法
[root@ccscripts]# sh teshu.sh a b c
teshu.sh
a b c
[root@cc scripts]# cat teshu.sh
#! /bin/bash
echo $0
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}${13} ${14} ${15}
echo $#
[root@ccscripts]# sh teshu.sh {a..z}
teshu.sh
a b c d e f g h i j k l m n o
26
$? 获取执行行上一个指令的返回值(0为成功,非0为失败)
查找方法man bash,而后搜索 Special Parameters
[root@cc ~]# cd qqq
-bash: cd: qqq: No such file or directory
[root@cc ~]# echo $?
127
[root@cc ~]# pwd
/root
[root@cc ~]# echo $?
0
$?返回值参考
0表示运行成功
2权限拒绝
1~125 表示运行失败,脚本命令、系统命令错误或参数传递错误。
126找到该命令,但没法执行
127未找到要运行的命令
>128命令被系统强制结束
生产环境
用于判断命令、脚本或函数等程序是否执行成功
若在脚本中调用执行“exit数字”,则会返回这个数字给“$?”变量。
若是在函数中使用“return数字”,则会以函数返回值的形式传给“$? "。
[root@cc scripts]# cat teshu.sh
#! /bin/bash
echo $0
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}${13} ${14} ${15}
echo $#
if[ $1 == 1 ]
then
exit 22
else
exit 33
fi
[root@ccscripts]# sh teshu.sh 1
teshu.sh
1
1
[root@ccscripts]# echo $?
22
[root@ccscripts]# sh teshu.sh 2
teshu.sh
2
1
[root@ccscripts]# echo $?
33
算术运算符号
运算符 |
意义 |
++ -- |
增长及减小,可前置也可放在结尾 |
+ - ! ~ |
一元的正号与负号,非,逻辑与位的取反 |
* / % |
乘法 除法 取余 |
+ - |
加法 减法 |
< <= > >= |
比较符号 |
== != |
相等 不相等 |
& |
向左位移 向右位移 |
^ |
位的AND |
| |
位的异或 |
&& |
位的或 |
|| |
位的OR |
?: |
条件表达式 |
= += -= |
赋值运算符 |
** |
幂运算 |
[root@cc scripts]# a=$((2-1))
[root@cc scripts]# echo $a
1
[root@cc scripts]# a=$((a++))
[root@cc scripts]# echo $a
1
[root@ccscripts]# a=$((a++))
[root@cc scripts]# echo $a
1
[root@ccscripts]# a=$((++a))
[root@cc scripts]# echo $a
2
[root@cc scripts]# echo $a
2
[root@ccscripts]# a=$((++a))
[root@cc scripts]# echo $a
3
变量a在前,表达式的值为a,而后a自增或自减,变量a在符号后,表达式值自增或自减,而后a值自增或自减。
[root@cc scripts]# cat calculator.sh
#!/bin/sh
echo $(($1))
[root@cc scripts]# sh calculator.sh 3+2-2*2/1
1
[root@cc scripts]# echo $[1+1]
2
[root@cc scripts]# echo $[1*3]
3
[root@cc scripts]# cat calculator.sh
#!/bin/sh
echo $(($1))
a=6
b=2
利用位置变量
[root@cc scripts]# cat calculator.sh
#!/bin/sh
echo $(($1))
a=$6
b=$2
判断某些条件是否成立,成立执行一种命令,不成立执行另一种命令。
格式:[ 测试表达式 ]
方法一
[root@ccscripts]# [ -f /etc/hosts ]
[root@cc scripts]# echo $?
0
[root@ccscripts]# [ -f /etc/host ]
[root@cc scripts]# echo $?
1
方法二
[root@ccscripts]# [ -f /etc/hosts ]&&echo TRUE||echo FALSE
TRUE
[root@ccscripts]# [ -f /etc/host ]&&echo TRUE||echo FALSE
FALSE
经常使用文件测试操做符号 |
说明 |
-f文件, file |
文件存在且为普通文件则真,即测试表达式成立 |
-d文件, directory |
文件存在且为目录文件则真,即测试表达式成立 |
-s文件, size |
文件存在且文件大小不为0则真,即测试表达式成立 |
-e文件, exist |
文件存在则真,即测试表达式成立。只要有文件就行,区别-f |
-r文件, read |
文件存在且可读则真,即测试表达式成立 |
-w文件,write |
文件存在且可写则真,即测试表达式成立 |
-x文件,executable |
文件存在且可执行则真,即测试表达式成立 |
-L文件,link |
文件存在且为连接文件则真,即测试表达式成立 |
f1 -nt f2, newer than |
文件f1比f2新则真,即测试表达式成立,根据文件修改时间计算 |
f1 -ot f2, older than |
文件f1比f2旧则真,即测试表达式成立,根据文件修改时间计算 |
字符串测试操做符的做用:比较两个字符串是否相同、字符串长度是否为零,字符串是否为NULL。Bash区分零长度字符串和空字符串。
经常使用字符串测试操做符 |
说明 |
-z "字符串" |
若串长度为0则真,-z理解为zero |
-n "字符串" |
若串长度不为0则真,-n理解为no zero |
"串1" = "串2" |
若串1等于串2则真,可使用“==”代替“=” |
"串1" != "串2" |
若串1不等于串2则真,但不能使用“!==”代替 |
特别注意,以上表格中的字符串测试操做符号务必要用""引发来。[ -z "$string" ] 字符串比较,比较符号两端最好有空格,参照系统脚本。 [ "$passwd" = "john ] |
[root@ccscripts]# [ -z " " ]&&echo TRUE||echo FALSE
FALSE
[root@ccscripts]# [ -z "" ]&&echo TRUE||echo FALSE
TRUE
[root@cc scripts]# [ -n "" ]&&echo TRUE||echo FALSE
FALSE
[root@ccscripts]# [ "aa" == "bb" ]&&echo TRUE||echo FALSE
FALSE
[root@cc scripts]# [ "aa" != "bb" ]&&echoTRUE||echo FALSE
TRUE
在[]中使用的比较符 |
说明 |
-eq |
equal等于 |
-ne |
not equal不等于 |
-gt |
greater than大于 |
-ge |
greater equal大于等于 |
-lt |
less than小于 |
-le |
less equal小于等于 |
[root@cc scripts]# [ 1 -le 2 ]&&echoTRUE||echo FALSE
TRUE
[root@cc scripts]# [ 1 -ne 2 ]&&echoTRUE||echo FALSE
TRUE
[root@cc scripts]# [ 1 -eq 2 ]&&echoTRUE||echo FALSE
FALSE
[root@cc scripts]# [ 1 -lt 2 ]&&echoTRUE||echo FALSE
TRUE
[root@cc scripts]# [ 1 -gt 2 ]&&echoTRUE||echo FALSE
FALSE
在[]中使用的逻辑操做符 |
说明 |
-a |
与and,两端都为真则真 |
-o |
或or,有一个真则真 |
! |
非not,相反则真 |
[root@cc scripts]# [ "1" !="2" -a 1 -eq 2 ]&&echo TRUE||echo FALSE
FALSE
[root@cc scripts]# [ "1" !="2" -o 1 -eq 2 ]&&echo TRUE||echo FALSE
TRUE
多个[]之间的逻辑操做符是&&或||
2. &&前面成功执行后面
3. || 前面不成功执行后面