shell脚本编程基础(1)

要想玩转Linux系统,编写shell脚本是必须要掌握的技能。那什么是shell编程呢?简单来说,shell编程就是对多个Linux命令进行逻辑处理。

本节索引

一、编程基础

二、脚本基本格式

三、变量

四、条件测试

五、配置用户环境

 

要想玩转Linux系统,编写shell脚本是必须要掌握的技能。那什么是shell编程呢?简单来说,shell编程就是对多个Linux命令进行逻辑处理。

下面,我们从编程的基础开始讲起:

timg_image&quality=80&size=b9999_10000&sec=1523364020366&di=4d83295488832abeb6fb

 

一、编程基础

1.什么是程序?

程序是指:指令+数据

程序编程风格可分为:

过程式:以指令为中心,数据服务于指令(关注过程,小软件开发)

对象式:以数据为中心,指令服务于数据(关注结果,适合开发大型软件)

 

2.程序的执行方式

计算机:运行二进制命令

编程语言:

低级:汇编

高级:

编译:高级语言–>编译器–>目标代码 (由程序员完成编译器翻译过程,安全性相对好)

java,C#

解释:高级语言–>解释器–>机器代码 (由电脑完成解释器翻译过程,安全性不如编译型)

shell,perl,python

 

shell程序:提供了编程能力,解释执行

 

 

3.编程基本概念

编程逻辑处理方式:

顺序执行

循环执行

选择执行

 

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

编程语言的基本结构:

各种系统命令的组合

数据存储:变量、数组

表达式:a+b

语句:if

 

二、脚本基本格式

格式要求:

首行shebang机制(即声明脚本使用哪种编程语言)

如:         #!/bin/bash

#!/bin/python

 

shell脚本的用途有:

自动化常用命令

执行系统管理和故障排除

创建简单的应用程序

处理文本或文件

 

运行脚本:

1.给予执行权限,执行

2.直接运行解释器,将脚本作为解释器程序的参数运行

 

脚本规范:

脚本代码开头约定:

1.第一行一般为调用使用的语言

2.程序名,避免更改文件名为无法找到正确的文件

3.版本号

4.更改后的时间

5.作者相关信息

6.该程序的作用,及注意事项

7.最后是各版本的更新简要说明

 

脚本示例:

#!/bin/bash

# ——————————————

# Filename:    hello.sh # Revision:    1.1

# Date:        2018/04/01

# Author:      wangx

# Email:       wangx@gmail.com

# Website:     www.donlihuoguo.cn

# Description: This is the first script

# ——————————————

# Copyright:   2018 wang

# License:     GPL  echo “hello world”

 

脚本调试:

bash -n script  检查脚本的语法错误

bash -x script  调试脚本执行

 

三、变量

定义变量时,变量名不加$符号,如:

my_name=”wangx”

*变量命名规则:

1.数字、字母、下划线,不能以数字开头

2.不能使用程序中的保留字:如if,for等

3.做到见名知意

 

注意:

引用变量一般需加$

赋值变量:

name=” ”   要加引号

存放多行字符时”$name”变量外加双引号可保留换行格式

 

*bash变量的种类

局部变量、全局变量、本地变量、位置变量、特殊变量

局部变量:只在当前shell进程生效,对当前shell之外其他shell进程,包括父shell和子shell都无效

全局变量:生效范围在当前shell进程及其子进程;父进程变量可以传给子进程,子进程变量不可向上传给父进程

数字变量:$10以上的变量需要加花括号${10}

特殊变量:$1,$@,$*,$#,$0等、

$1,$2,…:对应第1、第2参数,shift[n]换位置

$0:命令本身

$*:传递给脚本的所有参数,每个参数合为一个字符串

$@:传递给脚本的所有参数,每个参数为独立字符串

$#:传递给脚本的参数的个数

$@$*只在被双引号包起来的时候才会有差异

set–         清空所有位置变量

 

注:怎么判断变量前加不加$符号?

如果命令能识别变量就不加$,如果命令不能识别变量加$;

养成好习惯:编完脚本将变量用unset删掉;

 

()中使用的命令为一次性的,小括号中相当于在子进程中执行命令

注:小括号中所说的子进程与常规的子进程不是一回事

例如:x=1;echo $$;(echo $$)中显示进程号一致

 

{ ;}中使用命令时在当前shell环境中执行,不开启子进程影响当前shell环境

 

*变量运算

bash中的算术运算:help let

+,-,*,/,%取余,**乘方

实现算术运算:

1.let var=算术表达式

2.var=$[算术表达式]

3.var=$((算术表达式))

 

注:算术运算过程中,空格尽量删除

条件测试过程中,能加空格地方尽量加空格

正则条件测试时,正则表达式不加引号

 

四、条件测试

 

测试命令:

test EXPRESSION

[ EXPRESSION ]

[[ EXPRESSION ]]    双括号一般用于左侧字符匹配右侧扩展正则表达式

注:EXPRESSION前后必须有空白字符

 

评估布尔声明,以便用在条件性执行中:

若真,则返回0

若假,则返回1

 

例如:#a=1;b=2

#[ $a -eq $b ]

#echo $?

#1

#a=2;b=2

#[ $a -eq $b ]

#echo $?

#0

 

条件性的执行操作符

&&代表条件性的AND THEN,前面执行结果$?=0时,继续执行&&后命令

||代表条件性的OR ELSE,前面执行结果$?不为0时,执行||后命令

 

test  与[  ]效果相同,注意括号里内容两边需加空格

-v VAR      变量VAR是否设置

 

数值测试:

-gt    是否大于(greater-than)

-ge   是否大于等于(greater-than-or-equal)

-eq   是否等于(equal)

-ne   是否不等于(not-equal)

-lt     是否小于(less-than)

-le    是否小于等于(less-than-or-equal)

字符串测试:

==    是否等于

>       ascii码是否大于ascii码

<       是否小于

!=     是否不等于

=~    左侧字符串是否能够被右侧的PATTERN所匹配

注:使用PATTERN匹配时,需要加双括号[[ ]];使用扩展的正则表达式,且正则表达式不能加引号

-z      字符串是否为空,空为真,不空为假

-n     字符串是否为不空,不空为真,空为假

注:用于字符串比较时的用到的操作应该都使用引号

字符串是否为空还可用[ “$name” == “” ]来测试。

文件相关测试:

存在性测试:

-a FILE     同-e

-e FILE 文件存在性测试,存在为真,否则为假

存在性及类别测试:

-b FILE 是否存在且为块设备文件

-c FILE 是否存在且为字符设备文件

-d FILE 是否存在且为目录文件

-f FILE 是否存在且为普通文件

-h FILE 同-L

-L FILE      是否存在且为符号链接文件

-p FILE 是否存在且为管道文件

-S FILE 是否存在且为套接字文件

文件权限测试:

-r FILE      是否存在且有可读权限

-w FILE 是否存在且有可写权限

-x FILE 是否存在且有可执行权限

文件特殊权限测试:

-u FILE 是否存在且拥有suid权限

-g FILE 是否存在且拥有sgid权限

-k FILE 是否存在且拥有sticky权限

文件大小测试:

-s FILE 是否存在且非空

文件是否打开:

-t fd:fd 文件描述符是否在终端已经打开

-N FILE 文件自从上一次被读取之后是否被修改过

-O FILE 当前有效用户是否为文件属主

-G FILE 当前有效用户是否文文件属组

 

注意:文件测试后跟空字符时,也反馈为True,如果要保证一个文件存在且满足测试条件时,

应表示为:例:[ -n “file” -a -d “file” ]

file文件是否存在且为目录文件

 

双目测试:

FILE1 -ef FILE2                 FILE1是否是FILE2的硬链接

FILE1 -nt FILE2                 FILE1是否新于FILE2(mtime)

FILE1 -ot FILE2                 FILE1是否旧于FILE2

 

*Bash的组合测试条件:

第一种方式:

COMMAND1 && COMMAND2      并且

COMMAND1 || COMMAND2        或者

!COMMAND         非

 

第二种方式:

[ EXPRESSION -a EXPRESSION ]     并且

[ EXPRESSION -o EXPRESSION ]     或者

[ !EXPRESSION ]          非

注:优先级为:”!”最高,”-a”次之,”-o”最低

 

 

短路与&&

 

0&&0=0

0&&1=0

1&&0=0

1&&1=1

 

cmd1 && cmd2

如果cmd1为假,cmd2不需要执行,反之cmd1为真,需要cmd2执行

 

短路或||

 

0||0=0

0||1=1

1||0=1

1||1=1

 

cmd1 || cmd2

如果cmd1为真,cmd2不需要执行,反之cmd1为假,需要cmd2执行

 

异或 XOR ^

如果相同为假,反则为真

0 ^ 1 = 1

1 ^ 0 = 1

1 ^ 1 = 0

0 ^ 0 = 0

 

 

注意:[  ]和test用变量时,最好加双引号””避免出问题

 

false || { echo cmd1 ; echo cmd2 ; }

false || (echo cmd1 ; echo cmd2)

 

*使用read命令来接受输入

read         使用read来把输入值分配给一个或多个shell变量

-p     指定要显示的提示

-s    静默输出,一般用于密码

-n     N指定输入的字符长度N

-d     ‘字符’输入结束符,类型与输入重定向的<<EOF

-t N  TIMEOUT为N秒,N秒内无输入将自动退出

read命令从标准输入中读取单词,并给每个单词分配一个变量

例如:

read -p “Enter a filename:” FILE    标准输入将赋予变量$FILE

read命令从标准输入中读取单词,并给每个单词分配一个变量

read 给多个变量赋值的方法:

(1)将多个变量输入一个文件中,用空格分开,输出重定向

read a b c < f

(2)用“>>>”分开:

read a b c <<< “x y z”

五、配置用户环境

bash的配置文件

按生效范围划分,存在两类:

全局配置:

/etc/profile

/etc/profile.d/*.sh

/etc/bashrc

个人配置:

~/.profile

~/.bashrc

shell登录的两种方式:

交互式登录:

1.直接输入账号密码登录

2.su – username 切换的用户

执行顺序:/etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –> ~/.bashrc–> /etc/bashrc

非交互式的登录:

1.su usernme

2.图形界面打开的终端

3.执行脚本

4.任何其他的bash实例

执行顺序:~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

注:只在交互式登录生效:/etc/profile,~/.bash_profile

配置执行文件按功能划分,存在两类:

profile类和bashrc类

Profile类:为交互式登录的shell提供配置

全局生效:/etc/profile ,/etc/profile.d/*.sh

个人生效:~/.bash_profile

功用:

(1)用于定义环境变量

(2)运行命令或脚本

Bashrc类:为非交互式和交互式登录的shell提供配置

全局生效:/etc/bashrc

个人生效:~/.bashrc

功用:

(1)定义命令别名和函数

(2)定义本地变量

修改profile和bashrc文件后使生效的两种方法:

(1)重新启动shell进程

(2).或sourc;例:.~/.bashrc

注意: .或source执行脚本表示将在当前进程运行,而不是开启一个子进程运行(配置文件一般用此方式执行)

bash执行脚本则是开启一个进程执行(运行脚本一般用此方式执行)

Bash退出任务

保存在~./.bash_logout文件中(用户)

在退出登录shell时运行

可用于:

创建自动备份

清除临时文件

清除操作历史等

特殊的变量$-

#echo $-

#hibBH

h:hash缓存功能;set -h,关闭hash功能;set +h,开启hash功能

i:代表交互式shell

m:打开监控模式

B:大括号扩展

H:history,命令操作历史

bash展开命令的优先级:

把命令行分成单个命令词

展开别名

展开大括号{}

展开波浪符~

命令替换$()和

再次把命令行分成命令词

展开文件通配(*、?等)

I/O重定向

运行命令

 

 

 

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/95644

发表评论

登录后才能评论

This site uses Akismet to reduce spam. Learn how your comment data is processed.

联系我们

400-080-6560

在线咨询:点击这里给我发消息

邮件:1823388528@qq.com

工作时间:周一至周五,9:30-18:30,节假日同时也值班