Shell脚本构成与变量介绍

目录

一、shell脚本基础

1. 概述与构成

2. shell的作用

3. 脚本执行逻辑及执行方式

4. 脚本错误调试

二、shell脚本应用

1. 重定向与管道符

1.1 重定向

1.2 多行重定向

1.3 管道符

2. 自定义变量

2.1 常见Shell变量的类型

2.2 命名要求

2.3 符号使用 

2.4 变量追加值

2.5 read -p

3. 变量作用范围

4. 变量的运算

4.1 expr整数运算

4.2 其他运算方法

 4.3 随机数生成器变量

5. 环境变量

5.1 概述特点

5.2 配置文件 

6. 只读变量

7. 位置变量

8. 预定义(状态)变量 


一、shell脚本基础

1. 概述与构成

Shell脚本是一种用Shell语言编写的脚本程序,它可以在Unix/Linux系统上运行。Shell脚本通常以.sh为文件扩展名,是一种方便的自动化工具,可以用来完成各种系统管理和任务自动化的工作。

  • Shebang(可选):在脚本文件的第一行可以指定Shebang,用于指定脚本使用的Shell解释器。例如,#!/bin/bash表示使用bash解释器执行脚本。
  • 注释:可以在脚本中使用注释来提供说明和解释。注释以#开头,可以单行注释或多行注释。
  • 变量定义:可以在脚本中定义变量,用于存储数据。变量名通常使用大写字母,等号=用于赋值。例如,name="John"定义了一个名为name的变量,并将其赋值为"John"。
  • 命令和操作:在脚本中可以使用各种命令和操作,用于执行特定的任务。可以使用系统命令、自定义函数、管道、重定向等。
  • 流程控制语句:可以使用流程控制语句来控制程序的执行流程。常见的流程控制语句包括if语句、for循环、while循环、case语句等。
  • 函数定义(可选):可以在脚本中定义函数,用于封装一段可重复使用的代码。函数可以接受参数,并返回结果。
  • 输入和输出:脚本可以接受命令行参数作为输入,并可以使用echo命令输出结果。

2. shell的作用

 Linux 系统中的Shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。 常见的Shell解释器程序有很多种,使用不同的Shell时,其内部指令、命令行提示符等方面会存在一些区别。通过/etc/shells文件可以了解当前系统所支持的Shell 脚本种类。

查看本机的shell信息:

[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

linux中常见的shell:

  • bash:基于gun的框架下发展的shell
  • csh:类似c语言的shell
  • tcsh:整合了csh提供了更多功能
  • sh:已经被bash替换
  • nologin:让用户无法登录  

3. 脚本执行逻辑及执行方式

脚本执行逻辑:

  • 顺序执行:程序按从上到下顺序执行
  • 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
  • 循环执行:程序执行过程中需要重复执行多次某段语句

执行方式:

① 使用绝对或者相对路径执行(需要加执行权限)

[root@localhost ~]# vim ping.sh
[root@localhost ~]# chmod +x ping.sh  #添加执行权限
#!/bin/bash
ping -c1 192.168.190.100
[root@localhost ~]# /root/ping.sh     #绝对路径执行
[root@localhost ~]# ./ping.sh         #相对路径执行

② 直接使用解释器(不需要加执行权限)

[root@localhost ~]# chmod -x ping.sh
[root@localhost ~]# bash ping.sh

③ source和 . (不需要加执行权限)

[root@localhost ~]# source ping.sh
[root@localhost ~]# . ping.sh 

三种执行方式对当前环境影响:

[root@localhost ~]# vim cd.sh
#!/bin/bash
cd /opt
ls
[root@localhost ~]# chmod +x cd.sh
[root@localhost ~]# /root/cd.sh 
rh
[root@localhost ~]# pwd
/root
[root@localhost ~]# ./cd.sh 
rh                                    #使用子shell执行,不切环境
[root@localhost ~]# pwd
/root
[root@localhost ~]# bash cd.sh 
rh                     
[root@localhost ~]# pwd
/root                                 #使用子shell执行,不切环境
[root@localhost ~]# source cd.sh 
rh
[root@localhost opt]# pwd
/opt                                  #使用本shell执行,切环境
[root@localhost ~]# . cd.sh 
rh                
[root@localhost opt]# pwd
/opt                                  #使用本shell执行,切环境

4. 脚本错误调试

① 命令错误

默认后续的命令还会继续执行,用bash -n无法检查出来 ,可以使用bash -x进行观察

[root@localhost ~]# vim 1.sh
#!/bin/bash
mkdi 1                             #错误命令
echo 1                             #正确命令
[root@localhost ~]# bash 1.sh 
1.sh:行1: mkdi: 未找到命令
1                                  #错误命令不影响后续命令

② 语法错误

会导致后续的命令不继续执行,可以用bash -n检查错误,提示的出错行数不一定是准确的

[root@localhost ~]# vim 2.sh
#!/bin/bash
if [ 1 -eq 1 ];then
echo t
else
echo f
#fi
[root@localhost ~]# bash 2.sh 
2.sh:行7: 语法错误: 未预期的文件结尾

③ 逻辑错误

只能使用bash -x进行

注:

bash -n:脚本名称 (不在当前目录下加绝对路径),检查语法错误
bash -x:脚本名称 (不在当前目录下加绝对路径),逻辑错误

④ set -e,set -u

 在 脚本的前面输入set -e一旦出错立即停止

[root@localhost ~]# vim 3.sh
#!/bin/bash
set -e
cd /op
[root@localhost ~]# bash 3.sh 
3.sh: 第 3 行:cd: /op: 没有那个文件或目录

另外:set -u变量不存在不让执行

二、shell脚本应用

1. 重定向与管道符

1.1 重定向

重定向是一种功能,它允许用户更改命令的标准输入(stdin)和标准输出(stdout)的默认行为。这通常用于将命令的结果发送到不同的目的地,而不是仅仅显示在终端控制台上。

类型设备文件文件描述编号默认设备
标准输入/dev/stdin0键盘
标准输出/dev/stdout1显示器
标准错误输出/dev/stderr2显示器

交互式硬件设备:

  • 标准输入:从该设备接收用户输入的数据
  • 标准输出:通过该设备向用户输出数据
  • 标准错误:通过该设备报告执行出错信息
类型操作符用途
重定向输入<从指定的文件读取数据,而不是从键盘输入
重定向输出1>将输出结果保存到指定的文件(覆盖原有内容)
>>将输出结果追加到指定的文件尾部
标准错误输出2>将错误信息保存到指定的文件(覆盖原有内容)
2>>标准错误输出结果追加到指定的文件尾部
混合输出&>无论对错都可以重定向将标准输出、标准错误的内容保存到同一个文件中

案例:

不能将正确和错误一起显示出来 
[root@centos7 ~]#ls /data /xxx 1> /data/all.log 2>&1     
先将正确的重定向文件中,再将错误的重定向文件中
[root@centos7 ~]#ls /data /xxx 2> /data/all.log 1>&2     
先将错误的重定向文件中,再将正确的重定向文件中
[root@centos7 ~]#ls /data /xxx &> /data/all.log               不解释
[root@centos7 ~]#ls /data /xxx >& /data/all.log               同上
[root@centos7 ~]#ls /data /xxx   2>&1 1> /data/all.log   开始没有定义1,所以不符合要求 

1.2 多行重定向

可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用作命令的标准输入。 

[root@localhost ~]# cat > test << EOF     #EOF不区分大小写
> 1
> 2
> EOF
[root@localhost ~]# cat test
1
2

案例:修改密码

[root@localhost ~]# passwd fql << EOF
> 123456
> 123456
> EOF
更改用户 fql 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

1.3 管道符

“|”,将前面命令的结果当作后面命令的参数执行,管道符左边的命令一定要有标准输出,右边的命令一定可以接收标准输入。当右边无法接收标准输入,可以使用xargs命令代为接收。

[root@localhost ~]# cat /etc/passwd | wc -l
41
[root@localhost ~]# echo --help | xargs cat
用法:cat [选项]... [文件]...
将[文件]或标准输入组合输出到标准输出。
……

2. 自定义变量

2.1 常见Shell变量的类型

  • 自定义变量:由用户自己定义,修改和使用
  • 预定义变量:Bash中内置的一类变量shell,不能修改规定好的变量
  • 环境变量:由系统维护,用于设置工作环境,当前目录 、当前主机名、$PATH     
  • 只读变量:只可以读取不可以更改,常量   
  • 位置变量:通过命令行给脚本传递参数

2.2 命名要求

  • 区分大小写
  • 不能使程序中的保留字和内置变量:如:if, for,hostname 命令 a=
  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
  • 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH
  • 大驼峰 StudentFirstName
  • 小驼峰 studentFirstName
  • 下划线 student_name
定义变量:name=fql            
引用变量:$name  或  ${name}
调用变量:echo $name   或   echo ${name}
取消变量:unset name

2.3 符号使用 

双引号"  "            #弱引用,可以识别变量,可以避免空格错误
[root@localhost ~]# a=1
[root@localhost ~]# echo "$a"
1
[root@localhost ~]# a=1 2
bash: 2: 未找到命令...
[root@localhost ~]# a="1 2";echo $a
1 2

单引号'  '            #强引用,不能识别变量
[root@localhost ~]# a=1
[root@localhost ~]# echo '$a'
$a

反撇号`  `            #调用命令的执行结果,等于$()
[root@localhost ~]# time=`date`;echo $time
2024年 01月 24日 星期三 16:16:19 CST

大括号{  }             #定义变量名的范围
[root@localhost ~]# a=1;b=2
[root@localhost ~]# echo ${a}b
1b

2.4 变量追加值

格式:变量名+=变量值

[root@localhost ~]# a=1
[root@localhost ~]# a+=2;echo $a
12

2.5 read -p

从键盘输入的内容变成变量,交互式命令

[root@localhost ~]# read -p "现在的时间是:" time
现在的时间是:16点
[root@localhost ~]# echo $time
16点

[root@localhost ~]# vim 1.sh
#!/bin/bash
read -p "你的名字:" name
echo "你的名字是:$name"
[root@localhost ~]# bash 1.sh 
你的名字:lisi
你的名字是:lisi

3. 变量作用范围

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用。

方法:
格式1:定义好变量情况下 export 变量名
格式2:为定义变量情况下 export 变量名=变量值

[root@localhost ~]# a=1
[root@localhost ~]# echo $a
1
[root@localhost ~]# bash          #切换到子shell
[root@localhost ~]# echo $a       #子shell无法识别变量

[root@localhost ~]# 
[root@localhost ~]# pstree -p | grep -v grep | grep bash
           |-sshd(1097)-+-sshd(1520)---bash(1583)---bash(37606)  #37606为新打开的子shell

[root@localhost ~]# export a     #定义全局变量
[root@localhost ~]# bash
[root@localhost ~]# echo $a      #子shell可以识别变量
1
[root@localhost ~]# pstree -p | grep -v grep | grep bash
           |-sshd(1097)-+-sshd(1520)---bash(1583)---bash(37654)  #37654为新打开的子shell

4. 变量的运算

4.1 expr整数运算

expr只能进行整数的运算,格式:expr 变量1 运算符 变量2 [运算符 变量3]

运算符:

  • 加法 +
  • 减法 -
  • 乘法 \ *
  • 除法 /
  • 取余 (取模)%
[root@localhost ~]# expr a+b
a+b
[root@localhost ~]# expr $a + $b
3
[root@localhost ~]# expr $a - $b
-1
[root@localhost ~]# expr $a \* $b
2

4.2 其他运算方法

let 变量名=算术表达式
[root@localhost ~]# a=1;b=2
[root@localhost ~]# let c=a+b;echo $c
3

((变量名=算术表达式))
[root@localhost ~]# a=1;b=2
[root@localhost ~]# ((c = a+b));echo $c
3

变量名=$[算术表达式]
[root@localhost ~]# a=1;b=2
[root@localhost ~]# c=$[c=a+b];echo $c
3

变量=$(expr arg1 + arg2 ...)
[root@localhost ~]# c=$(expr $a + $b);echo $c
3

变量=`expr arg1 + arg2 ...`
[root@localhost ~]# c=`expr $a + $b`;echo $c
3

echo 算术表达式 | bc
[root@localhost ~]# echo $a+$b | bc
3

 4.3 随机数生成器变量

$RANDOM是一个特殊的环境变量,用于生成一个随机整数。每次访问$RANDOM时,它会返回一个0到32767(2^15-1)之间的随机整数,这个值是通过使用伪随机数生成器来生成的。

[root@localhost ~]# echo $[RANDOM]        #随机生成0-32767
17922
[root@localhost ~]# echo $[RANDOM%35]     #随机生成0-34
1
[root@localhost ~]# echo $[RANDOM%35+1]   #随机生成1-35
7

 随机生成颜色:

[root@localhost ~]# echo -e "\E[1;30mhello\E[0m"  
hello
#指定颜色,30-36共7种颜色
[root@localhost ~]# echo -e "\E[1;$[RANDOM%7+31]mhello\E[0m"
hello
#随机颜色

5. 环境变量

5.1 概述特点

环境变量大体可以分为两类:全局环境变量、局部环境变量。前者变量名通常使用大写字母,后者变量名通常使用小写字母。可通过下述env、printenv命令查看当前所有的全局环境变量。

常用的环境变量:

  • $USER 表示用户名称
  • $HOME 表示用户的宿主目录
  • $LANG 表示语言和字符集
  • $PWD 表示当前所在工作目录
  • $PATH 表示可执行用户程序的默认路径

 特点:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
  • 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
  • 一般只在系统配置文件中使用,在脚本中较少使用

5.2 配置文件 

/etc/profile如果修改此文件会作用于所有用户

~/.bash_profile 用户独立的配置文件,修改这个文件只作用于当前用户

6. 只读变量

只读变量是一种特殊类型的变量,其值不能被修改或重写。一旦将变量声明为只读,就无法再对其进行赋值操作。 变量值不允许修改(重新赋值)的情况,无法使用unsets删除,最快方法重启。

[root@localhost ~]# a=1
[root@localhost ~]# readonly a
[root@localhost ~]# echo $a
1
[root@localhost ~]# a=2
bash: a: 只读变量
[root@localhost ~]# unset a
bash: unset: a: 无法反设定: 只读 variable

7. 位置变量

位置变量也称为位置参数,使用$1、$2、$3、…、$9 表示

[root@localhost ~]# vim 1.sh
#!/bin/bash
echo "$1"            位置1
echo "$2"            位置2
echo "${10}"         位置10,不使用括号,只能识别第一个参数
[root@localhost ~]# bash 1.sh {1..20}
1
2
10

8. 预定义(状态)变量 

存在一些预定义变量(也称为状态变量),它们提供了有关系统和正在发生的操作的信息。这些变量不需要事先声明,而是由操作系统自动提供。

  • $*:表示所有位置参数的内容看成一个整体返回 返回所有
  • $@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回 返回所有
  • $?:表示前一条命令执行后的返回状态,返回值为0表示执行正确,返回任何非0值均表示执行出现异常
  • $#:表示命令行中位置参数的总个数
  • $0:表示当前执行的脚本或程序的名称 当前脚本的名字
  • $$:当前bash的进程id
  • $!: 后台任务最后一个id
[root@localhost ~]# vim 1.sh
#!/bin/bash
echo "$*"
echo "$@"
echo "$?"
echo "$#"
echo "$0"
echo "$$"
echo "$!"

[root@localhost ~]# bash 1.sh {1..10}
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
0
10
1.sh
38866

注: 

 当使用“$0”预定义变量时,如果执行的是软链接文件,则输出的是当前执行的软链接文件名

[root@localhost ~]# ln -s 1.sh a
[root@localhost ~]# ll a
lrwxrwxrwx. 1 root root 4 1月  24 18:47 a -> 1.sh
[root@localhost ~]# bash a
a
  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值