Linux系统——shell脚本编程基础介绍

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     非交互式语言

由于centosredhat linux默认的shellbash,你可以加,也可以不加,为了规范加上最好

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执行命令但不在当前shellsource 在当前的bash环境下读取并执行脚本中的内容,并且脚本可以是无执行权限




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 (n1...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 学习相关内容

更多精彩内容请关注公众号后续更新

Linux系统——shell脚本编程基础介绍
长按关注公众号—友侃有笑