shell脚本编程基础

 

 

 

 

 

 

一编程基础

 

   1程序编程风格

 

 


程序:指令+数据java

 

程序编程风格:node


(1)过程式:以指令为中心,数据服务于指令。python

 

程序员把主要的精力集中在程序指令上,一步步怎么作的。好比C、C++符合人类处理事情的逻辑关系的,不过这适合简单的事情。程序员

 

对于大型的应用程序的开发这种方法是很是难的,会产生混乱。web

 


(2)对象式:以数据为中心,指令服务于数据。shell

经过指令处理数据,获得咱们关心的结果,程序最重要的功能是在处理数据上。编程

 

对于大型的事是采用这种方法。好比盖大楼要雇用一些团队,把大的工做分解成小的工做。设计图纸有专门的设计院来完成,搬砖要有专门的工人。vim

 

对于大的项目来讲不太关注每一个流程了。更多的考虑把任务分包给具体的人,每一个团队作本身的事,作完就好,不关心作事的方式。centos

 

就像有句话叫作只要白猫黑猫能抓住老鼠的就是好猫。数组

 

大项目使用的是面向对象,而小项目是面向过程。咱们如今编脚本仍是面向过程式的。

 

 

 

 

 

 

   2程序的执行方式

 


(1)计算机:运行二进制指令

 

计算机只能识别二进制。计算机真的要运行一个程序,要把人类可以理解的东西转化成二进制。

 


(2)编程语言:

 

1低级:汇编

 

汇编语言也是字符串,和机器语言是一一对应的,要把汇编语言转化成机器码进行分析。

 

 

2高级:

 

<1>编译

 

<1>编译:高级语言-->编译器-->目标代码   好比java,C#

 

编译型的语言要转化成二进制的内容才会执行,须要有编译器生成二进制的东西。

 

好比ls命令是一个二进制的东西,是编译完了的最终结果。

 

咱们看里面的东西是乱码的。

 

 

 

[root@centos73 ~]# cat  /bin/ls

 


 

 

 

 

 

 

<2>解释


<2>解释:高级语言-->解释器-->机器代码   好比shell, perl, python

 

 

 

对于解释型语言,在运行的时候,系统后台有一个解释器,自动把文字的东西解释成机器代码。

 

虽然也是转换成二进制的,可是是放在内存中的,不须要生成文件。

 

因此感受好像就是一个文本在运行。

 

而shell里面的解释器有不少,好比bash shell。

 

shell程序就是把咱们所学的命令按照逻辑关系写到文本中。提供了编程能力,翻译成机器码解释执行。

 

 

编译是要人工去作,而解释是系统自动完成的,因此在代码出现问题须要修改编译更麻烦。

 

Java,C语言事先要进行编译一下,变成了看不懂的二进制的文档,而不是解释执行。

 

 

 

 

 

 

 

 

 

 

   3编程基本概念——编程逻辑处理方式

 

 

1顺序执行。就是指令按照顺序执行。

 

2循环执行。重复的执行某个指令,好比建立100个帐号。

 

3选择执行。当知足某个条件执行一个指令,而当知足另一个条件的时候执行另外的指令。

 

shell编程:过程式、解释执行


编程语言的基本结构:各类系统命令的组合,数据存储:变量、数组,表达式: a + b,语句:if。




 

 

 

 

二shell脚本基础

 

 

   1shell脚本介绍

 

 

规范的shell脚本的语法要求,包含一些命令或声明,并符合必定格式的文本文件格式要求。


格式要求:首行shebang机制

 

#在英文里面叫作sharp,!叫作bang.#!就是shebang

 

第一行要告诉shell,使用的是那种shell,对于其余语言写上本身语言的类型便可。

 


#!/bin/bash


#!/usr/bin/python


#!/usr/bin/perl 

 

 

 

 

 

 

   2shell脚本的用途

 

 

  1. 自动化经常使用命令,作事要3次以上建议写脚本。
  2. 执行系统管理和故障排除
  3. 建立简单的应用程序
  4. 处理文本或文件

 

 

 

 

 

   3shell脚本的执行原理

 

 

当执行一个命令的时候,先判断是否是别名,内部命令。若是不是就看是不是外部命令,外部命令是对应PATH变量的路径来找的。

 

在Linux里面,执行命令是不会寻找当前目录的

 

 

而当shell脚本运行时,它会先查找系统环境变量ENV里面的PATH路径。

 

该变量指定了环境文件(加载顺序通常默认是/etc/profile、.bash profile.、~/.bashrc, /etc/bashrc等),在加载了上述环境变量文件后, shell就开始执行shell脚本中的内容。

 


shell脚本是从上至下、从左至右依次执行每一行的命令及语句的,即执行完了一个命令后再执行下一个。

 

 

若是在shell脚本中遇到子脚本(即脚本嵌套)时,就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句。

 


一般状况下,在执行shell脚本时,会向系统内核请求启动一个新的进程,以便在该进程中执行脚本的命令及子shell脚本。

 

 

 

基本流程如图所示:

 

 

 

 

 

 

 

 

 PATH=/root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

注意第1个路径是我后来加的,为了执行方便

[root@centos733 ~]# env
XDG_SESSION_ID=1 HOSTNAME=centos733.huawei.com SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.137.34 58583 22 SELINUX_USE_CURRENT_RANGE= 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:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=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:*.webm=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=/root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin PWD=/root LANG=en_US.UTF-8 SELINUX_LEVEL_REQUESTED= HISTCONTROL=ignoredups SHLVL=1 HOME=/root LOGNAME=root SSH_CONNECTION=192.168.137.34 58583 192.168.137.73 22 LESSOPEN=||/usr/bin/lesspipe.sh %s XDG_RUNTIME_DIR=/run/user/0 _=/usr/bin/env

 

 

 

 

 

 

 

 

   4建立shell脚本的步骤

 

 

第一步:使用文本编辑器,好比常见的vim来建立文本文件。

 

 

第一行必须包括shell声明序列#!/bin/bash

 

添加注释,注释以#开头

 

 

第二步:运行脚本,给予执行权限,在命令行上指定脚本的绝对或相对路径。直接运行解释器,将脚本做为解释器程序的参数运行。

 

 

因为系统默认的是使用bash,因此能够省略不写,可是把脚本拷到其余的机器上,不必定使用的是这个bash。为了不产生BUG建议都要写。

 

为了让程序更易于维护,要加注释,包括做者,版本号,功能等等。

 

注意shell自己是开源的,无法加密的。

 

 

 

 

 

   5shell脚本规范

 

 

 

脚本代码开头约定

一、第一行通常为调用使用的语言

二、程序名,避免更改文件名为没法找到正确的文件

三、版本号

四、更改后时间

五、做者相关信息

六、该程序的做用,及注意事项

七、最后是各版本的更新简要说明

 

 

 

 

 

   6shell脚本的基本结构

 

 

第一行  #!SHEBANG

变量 CONFIGURATION VARIABLES

函数 FUNCTION DEFINITIONS

主要代码 MAIN CODE

 

 

 

 

 

   7shell脚本执行的方式

 

 

Shell脚本的执行一般能够采用如下几种方式


1 bash   script-name或sh script-name

 

这是当脚本文件自己没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时须要使用的方法。

 

推荐使用这种方法

 

 


2 path/script-name或/script-name 

 

在当前路径下执行脚本(脚本须要有执行权限),须要将脚本文件的权限先改成可执行(即文件权限属性加x位),

 

 

具体方法为chmod +x script-name,而后经过脚本绝对路径或相对路径就能够直接执行脚本了。

 


在企业生产环境中,很多运维人员在写完Shell脚本以后,因为忘记为该脚本设置执行权限,而后就直接应用了,结果致使脚本没有按照本身的意愿手动或定时执行,

 

对于这一点,避免出现该问题的方法就是用第1种方法替代第2种。

 

 

 


3 source script-name或. script-name

 

这种方法一般是使用source或"." (点号)读入或加载指定的Shell脚本文件(如san.sh),而后,依次执行指定的Shell脚本文件san.sh中的全部语句。

 

这些语句将在当前父Shell脚本father.sh进程中运行(其余几种模式都会启动新的进程执行子脚本)。

 

所以,使用source或“."能够将san.sh自身脚本中的变量值或函数等的返回值传递到当前父Shell脚本father.sh中使用。

 

这是它和其余几种方法最大的区别。

 


source或“."命令的功能是:在当前Shell中执行source或“."加载并执行的相关脚本文件中的命令及语句,而不是产生一个子Shell来执行文件中的命令。

 

注意"."和后面的脚本名之间要有空格。

 


source或"."至关于PHP开发的include的功能。HTTP服务软件Apache,Nginx等配置文件里都支持这样的用法。

 

 

 

 


4 sh<script-name或cat scripts-namelsh

 

一样适用于bash,不过不常见

 

不用循环语句来实现精简开机自启动服务就是经过将全部字符串拼接为命令的形式,而后经由管道交给bash操做

 

 

 

注意不写路径直接执行脚本,那么就把脚本放到PATH变量里面的路径去,即便是在其余的路径也能够执行。

[root@centos733 shell_scripts]# pwd
/root/shell_scripts
[root@centos733 shell_scripts]# echo $PATH /root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

 

 

 

 

运行第1个脚本

注意最后找一个集中的目录来存放本身写的脚本,便于查看和备份

#!/bin/bash

# Filename: hel1o.sh

# Revision: 1.1

# Date: 2018/06/01

#Author: wangm

# Description: This is the first script

echo "hello world"
 

 

 

 

 

 

1 bash   script-name或sh script-name

 

脚本是在 shell_scripts目录下写的,可是是在root目录下执行

[root@centos733 ~]# ll    shell_scripts/ -d
drwxr-xr-x. 3 root root 4096 Mar 14 21:50 shell_scripts/ [root@centos733 ~]# ll shell_scripts/hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh [root@centos733 ~]# bash hello.sh hello world [root@centos733 ~]# cat shell_scripts/hello.sh #!/bin/bash #Author=wang # Filename: hel1o.sh # Revision: 1.1 # Date: 2018/06/01 #Author: wangm # Description: This is the first script echo "hello world"

 

 

 

 

 

 

2 path/script-name或/script-name 

[root@centos733 ~]# ./shell_scripts/hello.sh
-bash: ./shell_scripts/hello.sh: Permission denied
[root@centos733 ~]# cd  shell_scripts/ [root@centos733 shell_scripts]# pwd /root/shell_scripts  [root@centos733 shell_scripts]# ./hello.sh -bash: ./hello.sh: Permission denied  [root@centos733 shell_scripts]# ll hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 hello.sh [root@centos733 shell_scripts]# chmod +x hello.sh [root@centos733 shell_scripts]# ./hello.sh hello world [root@centos733 shell_scripts]# cd [root@centos733 ~]# ./shell_scripts/hello.sh hello world [root@centos733 ~]# ./shell_scripts/hello.sh hello world  [root@centos733 ~]# ll shell_scripts/hello.sh -rwxr-xr-x. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh

 

 

 

 

 

 

 3 source script-name或. script-name

和法1同样不须要加执行权限也能够执行

[root@centos733 ~]# .  shell_scripts/hello.sh 
hello world
[root@centos733 ~]# source   shell_scripts/hello.sh hello world [root@centos733 ~]# chmod -x shell_scripts/hello.sh [root@centos733 ~]# ll shell_scripts/hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh [root@centos733 ~]# . shell_scripts/hello.sh hello world [root@centos733 ~]# source shell_scripts/hello.sh hello world

 

 

 

 

 

 

 

   8脚本语法检测和调试

 

 

1脚本语法检测

bash -n    /path/to/some_script   

检测脚本中的语法错误。注意bash -n对于语法错误是能够查出来的,可是对于命令写错是不能查出来的。

 

 

 

2 调试执行

bash   -x     /path/to/some_script

 

 

 

编写关于显示操做系统各类信息的脚本

[root@centos733 shell_scripts]# cat  OS.sh 
#!/bin/bash #Description: show system info echo "The host is `hostname`" echo "The kernel version is `uname -r`" echo "The CPU is `lscpu | grep "Model name:" | tr -s ' ' | cut -d : -f2`" cat /proc/meminfo | head -n1 echo "The IP is `ifconfig ens33 | grep netmask | tr -s ' ' | cut -d " " -f3`" 

 

 

 

 

 1脚本语法检测

[root@centos733 shell_scripts]# pwd
/root/shell_scripts
[root@centos733 shell_scripts]# bash  -n  OS.sh 

 

 

 

 

2 调试执行

 

跟踪每一步的执行结果。能够看出命令是分解执行的,同一行也是这样。

命令嵌套,因此看到是先执行里面的hostname,而后执行外面的echo

[root@centos733 shell_scripts]# bash  -x   OS.sh 
++ hostname
+ echo 'The  host is centos733.huawei.com'
The  host is centos733.huawei.com
++ uname -r + echo 'The kernel version is 3.10.0-862.el7.x86_64' The kernel version is 3.10.0-862.el7.x86_64 ++ lscpu ++ grep 'Model name:' ++ tr -s ' ' ++ cut -d : -f2 + echo 'The CPU is Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz' The CPU is Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz + cat /proc/meminfo + head -n1 MemTotal: 997980 kB ++ grep netmask ++ cut -d ' ' -f3 ++ tr -s ' ' ++ ifconfig ens33 + echo 'The IP is 192.168.137.73' The IP is 192.168.137.73

 

 

 

 

 

 

 

由于hostname是一个命令,咱们用echo调用他是要加上反引号,为了看起来更清晰,使用单引号引发来。

 

显示内核版本的命令是uname   -r

 

显示一下CPU的型号

[root@centos73 ~]# lscpu

Architecture:          x86_64

CPU op-mode(s):        32-bit, 64-bit

Byte Order:            Little Endian

CPU(s):                1

On-line CPU(s) list:   0

Thread(s) per core:    1

Core(s) per socket:    1

Socket(s):             1

NUMA node(s):          1

Vendor ID:             GenuineIntel

CPU family:            6

Model:                 142

Model name:            Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz

 

 

 

 

查看内存,使用命令free

显示当前系统的地址,调用命令是要在命令的左右两边加上反单引号。

[root@centos73 ~]# free  -h     -h, --human         show human-readable output

              total        used        free      shared  buff/cache   available

Mem:           992M        169M         82M         13M        739M        623M

Swap:          3.0G        520K        3.0G

 

 

[root@centos73 ~]# cat /proc/meminfo

MemTotal:        1015828 kB

MemFree:           84564 kB

MemAvailable:     638036 kB

Buffers:              36 kB

Cached:           656816 kB

SwapCached:          216 kB

Active:           333592 kB
相关文章
相关标签/搜索