Linux系统——shell脚本编程基础介绍
**1****、什么是shell**
它是一个命令解释器,在linux/unix操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种操作输出的结果,输出到屏幕返回给用户,可以是交互式与非交互式的方式进行会话
[root@backup~]# head -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
shell****脚本介绍:
当命令或语句不在命令行执行,而是通过一个程序文件执行时,这类文件就被称为shell脚本或shell程序文件,类似于WIN系统下面的批处理程序
**2、shell脚本语言的种类**
Bourneshell(包括shksh bash)
Cshell (csh)
在redhat和centos系统中,最常用的是bash
[root@backup ~]# cat /etc/redhat-release
CentOS release6.5 (Final)
[root@backup~]# tail -5 /etc/passwd
sshd:x:74:74:Privilege-separatedSSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
text:x:500:500::/home/text:/bin/bash
rsync:x:501:501::/home/rsync:/sbin/nologin
mysql:x:502:502::/home/mysql:/sbin/nologin
如何查看系统的默认shell
[root@backup~]# echo $SHELL
/bin/bash
不同的系统版本,bash版本也不同
[root@backup~]# bash –version
GNU bash, version 4.1.2(1)-release(x86_64-redhat-linux-gnu)
Copyright(C) 2009 Free Software Foundation, Inc.
LicenseGPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This isfree software; you are free to change and redistribute it.
There is NOWARRANTY, to the extent permitted by law.
**3、shell脚本编辑规范**
通常在编辑器(vi/vim)中编写,由linux命令、bashshell命令、程序结构控制语句和注释内容组成
脚本规范:
1****、第一行一般都是指定由哪个程序来执行解释脚本中的命令内容
[root@backup~]# cat /etc/init.d/nfs
#!/bin/sh
[root@backup~]# ll /bin/sh
lrwxrwxrwx.1 rsync rsync 4 Sep 29 11:56 /bin/sh - bash
不同的脚本语言第一行开头内容有所不同,如下所示
#!/bin/sh
#!/usr/bin/awk 做C语言开发
#!/bin/sed
#!/usr/bin/expect 非交互式语言
由于centos和redhat linux默认的shell是bash,你可以加,也可以不加,为了规范加上最好
2****、加上作者信息与版本信息与功能
3****、脚本注释
说明脚本的内容与作用,可以自成一行,也可以放在命令后面,做命令的解释所用,在实际生产环境中这种注释内容是非常重要,规范的注释内容可以方便后续管理与其它人员查看,但尽量不要用中文注释内容
4****、脚本以.sh为扩展名
方便后续查看哪些是脚本
5****、代码书写习惯
成对的内容一次性写出如:‘’“” {} [ 里面的内容前后需有空格 ] ()
流程控制语句一次性写完
if []
then
返回中间输入内容
fi
通过缩进让代码容易读
4、shell脚本执行
它执行时,会先查看系统全局变量里的内容,然后从环境变量开始执行,再执行shell脚本的内容
执行几种方法:
1****、bashscripts-name或sh scripts-name
通常为脚本文件没有执行权限时常用的方法
[root@backup~]# cd /server/scripts/
[root@backupscripts]# sh baktable_auto.sh
[root@backupscripts]# ll
total 20
-rw-r–r–.1 root root 236 Oct 11 00:42bakfenku_auto.sh
-rw-r–r–.1 root root 356 Oct 11 03:10baktable_auto.sh
-rw-r–r–.1 root root 739 Oct 12 13:36bak_zhuku.sh
-rw-r–r–.1 root root 1063 Oct 12 13:22 congku.sh
-rw-r–r–.1 root root 522 Oct 11 07:54 dump.sh
2、path/scripts-name或./ scripts-name
这种执行方法,必须需要执行权限,通过chmod +x scripts-name
[root@backupscripts]# ./congku.sh
-bash:./congku.sh: Permission denied
[root@backupscripts]# /server/scripts/dump.sh
-bash:/server/scripts/dump.sh: Permission denied
3、source scripts-name或 . scripts-name
此种方法是将脚本里的变量值返回到当前的shell中使用
[root@backupscripts]# vi text.sh
user=
whoami
[root@backupscripts]# echo $user
[root@backupscripts]# . text.sh
[root@backupscripts]# echo $user
root
注:**.表示从当前的shell中执行操作,exec执行命令但不在当前shell,source 在当前的bash**环境下读取并执行脚本中的内容,并且脚本可以是无执行权限
**5、shell变量介绍**
5、shell变量介绍
变量分为:环境变量(全局变量)与局部变量
环境变量:
用于定义shell的运行环境,保证它的命令正确执行,shell通过环境变量来确定登陆用户名、命令路径、终端类型、登陆目录等,所有的环境变量都是系统的全局变量,环境变量也可以在命令行中设置,但用户退出时这些变量也会丢失,因此可以将变量配置在用户家目录中.baxh_profile文件中或全局配置/etc/profile文件或者/etc/profile.d/中定义,每次用户登陆时这些变量都将初始化
环境变量均为大写,环境变量应用于用户进程前,必须用export导出
[root@backupscripts]# echo $HOME
/root
[root@backupscripts]# echo $UID
0
[root@backupscripts]# echo $USER
root
[root@backupscripts]# echo $HOSTNAME
backup
自定义环境变量
export 变量名=值
[root@backup~]# NAME=beijing
[root@backup~]# export NAME
[root@backup~]# echo $NAME
beijing
显示和取消环境变量
[root@backup~]# env
HOSTNAME=backup
SELINUX_ROLE_REQUESTED=
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.1.20055802 22
SELINUX_USE_CURRENT_RANGE=
QTDIR=/usr/lib64/qt-3.3
OLDPWD=/server/scripts
QTINC=/usr/lib64/qt-3.3/include
SSH_TTY=/dev/pts/0
NAME=beijing
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
取消变量
unset USER 就可以直接取消
局部变量
本地变量只在shell生存周期有效
普通变量
[root@backup~]# a=192.168.1.2-$a
[root@backup~]# b=’192.168.1.2-$a’
[root@backup~]# c=”192.168.1.2-$a”
[root@backup~]# echo “a=$a”
a=192.168.1.2-
[root@backup~]# echo “b=$b”
b=192.168.1.2-$a
[root@backup~]# echo “c=${c}”
c=192.168.1.2-192.168.1.2-
单引号里的内容是什么就输出什么,双引号定义变量时会将双引号里的内容进行解析再输出结果
[root@backup~]# test=
date
[root@backup~]# echo $test
Wed Oct 1223:09:23 EDT 2016
[root@backup~]# echo ‘$test’
$test
[root@backup~]# echo “$test”
Wed Oct 1223:09:23 EDT 2016
总结:无论定义变量还是输出变量,单引号,双引号,没有引号,都是上面的输出结果
如果使用命令做为变量,建议使用$(命令)
[root@backup~]# CMD=$(date)
[root@backup~]# echo $CMD
Wed Oct 1223:30:59 EDT 2016
[root@backup~]# echo /server/scripts/$CMD.txt
/server/scripts/WedOct 12 23:30:59 EDT 2016.txt
特殊变量****(重点)
位置变量
**$0 ** 获取当前执行的脚本文件名,包括路径
[root@backupshell]# vi 0.sh
echo $0
[root@backupshell]# sh 0.sh
0.sh
**$n (n是1…9)**,获取当前执行的脚本的第N个参数,n大于9的话,要用{},比如${10}
[root@backupshell]# vi n.sh
echo $1 $2$3 (取命令的第n个参数)
[root@backupshell]# sh n.sh ka ha li
ka ha li
**$# ** 获取当前脚本命令行中参数的总的个数
[root@backupshell]# vi n.sh
echo $1 $2$3
echo $#
[root@backupshell]# sh n.sh d d d d d
d d d
5
进程状态变量
$? 获取上一个命令的返回值,0表示成功,非0表示失败
[root@backupshell]# 123
-bash: 123:command not found
[root@backupshell]# echo $?
127
[root@backupshell]# ls
0.sh n.sh
[root@backupshell]# echo $?
0
0表示成功,2是权限不够,127是没有找到运行的命令
**$$ ** 获取当前执行的脚本的进程号
$* 获取当前shell的所参数,将所有命令行参数视为单个字符串
$@ 获取当前shell的所参数,将命令行每个参数视为一个字符串“$1 $2 $3”
[root@backupshell]# set “I am” a man
[root@backupshell]# echo $#
3
[root@backupshell]# for i in $*;do echo $i;done
I
am
a
man
[root@backupshell]# for i in $@;do echo $i;done
I
am
a
man **===============================**没加双引号没区别
[root@backupshell]# for i in “$*”;do echo $i;done
I am a man
[root@backupshell]# for i in “$@”;do echo $i;done
I am
a
man
注:man bash 学习相关内容
更多精彩内容请关注公众号后续更新
**长按关注公众号—友侃有笑**