Shell脚本——变量

Shell 脚本的介绍

常见快捷键

快捷键

描述

Ctrl + A

将光标移至行首

Ctrl + E

将光标移至行尾

Ctrl + C

终止操作

Ctrl + D

一般为结束输入

Ctrl + M

回车

Ctrl + U

删除光标至行首的所有内容

Ctrl + W

删除光标前面的一个单词(空格分隔)

Ctrl + S

挂起,冻结终端

Ctrl + Q

解除冻结终端

Alt + .

使用前一个命令的最后一个词

方向键(上下键)

历史记录

Tab键

补齐命令,选项、路径与文件名(补齐选项需要bash-completion软件包)

  • 安装新的解释器

[root@shell ~]# yum -y install ksh

[root@shell ~]# ksh

  • bash的优点

支持历史记录,快捷键,tab,管道,重定向,别名

  • 标准的的脚本构成

1、声明解释器

#!/bin/bash

2、注释脚本功能,变量含义,每个步骤要解决的问题,等... ...

3、具体代码

例:

[root@shell]# cd /shell

[root@shell shell]# vim test.sh

#!/bin/bash

#这是一个测试脚本

echo abc

[root@shell shell]# ll test.sh

-rw-r--r--. 1 root root 47 Jul 16 15:27 test.sh

[root@shell shell]# chmod u+x test.sh     //给用户执行权限,执行脚本

[root@shell shell]# ll test.sh

-rwxr--r--. 1 root root 47 Jul 16 15:27 test.sh

[root@shell shell]# /shell/test.sh

abc

[root@shell shell]# ./test.sh

abc

  • 注:脚本执行方式:

1、赋予x执行权限,然后使用绝对或相对路径运行该文件

2、使用解释器直接执行脚本,即使没有x权限也可以,调用bash解释器来解释脚本(也可以用别的解释器),新开启解释器进程执行脚本,脚本执行完毕后,新开启的解释器自动退出

[root@shell /]# chmod u-x /shell/test.sh

[root@shell /]# ll /shell/test.sh

-rw-r--r--. 1 root root 47 Jul 16 15:27 /shell/test.sh

[root@shell /]# bash /shell/test.sh

abc

[root@shell /]# sh /shell/test.sh

abc

[root@shell /]# ksh /shell/test.sh

abc

3、使用source命令执行脚本,也可以没有x权限,(用当前默认释器来解释脚本),不开启新解释器,使用当前解释器执行脚本

[root@shell /]# source /shell/test.sh

abc

source可以简写为 .

[root@server opt]# . test2.sh      //也可以执行

  • 注:脚本执行方式,调用解释器执行和source执行的区别

[root@shell ~]# vim /shell/test2.sh

#!/bin/bash

mkdir abc

cd abc

[root@server opt]# source test2.sh

[root@server abc]#        //使用source命令执行,使用当前解释器来执行命令,命令执行完会停留在当前状态

[root@server abc]# cd ..

[root@server opt]# ls

abc  test2.sh

[root@server opt]# rm -rf abc

[root@server opt]# bash test2.sh

[root@server opt]# ls     

abc  test2.sh      //调用新的解释器执行,是在当前解释器上又新开了一个解释器,新的解释器执行完命令后会自动结束进程,而默认解释器的状态是在/opt下,所以执行结果显示会在/opt,其实脚本已经被新的解释器所执行,使用ls查看可以看见新的解释器的执行效果

  • 编写一键部署yum脚本(test3.sh)

[root@server ~]# mkdir /etc/yum.repos.d/repo

[root@server ~]# cd /etc/yum.repos.d/

[root@server yum.repos.d]# mv *.repo repo      //将所有yum源放入repo中,以免影响下面脚本

[root@server yum.repos.d]# ls

repo

[root@server ~]# cd /opt

[root@server opt]# vim test3.sh

#!/bin/bash

echo "[base]

name=ceshi

baseurl=file:///mnt/

enable=1

gpgcheck=0" > /etc/yum.repos.d/ceshi.repo

mount /dev/cdrom /mnt

[root@server opt]# bash test3.sh

[root@server opt]# cd /etc/yum.repos.d/

[root@server yum.repos.d]# ls

ceshi.repo  repo

[root@server yum.repos.d]# yum repolist

  • 编写一键部署vsftpd脚本(test4.sh)

[root@server ~]# cd /opt

[root@server opt]# vim test4.sh

#!/bin/bash

yum -y install vsftpd &> /dev/null

systemctl start vsftpd

systemctl enable vsftpd

[root@server opt]# bash test4.sh

[root@server ~]# systemctl stop firewalld     //脚本写完关闭防火墙测试服务

#############################################################################

Shell脚本中的变量

常量:固定不变的内容(以上脚本所运用的都是变量)

变量:存储可能会发生变化的内容,增加脚本的灵活性

  • 变量类型

— 自定义变量

— 环境变量

— 位置变量

— 预定义变量

  • 自定义变量

— 变量名称必须使用字母,数字,下划线,不能以数字开头,不能使用特殊符号

[root@server ~]# a=10

[root@server ~]# echo $a

10

[root@server ~]# a=100

[root@server ~]# a=abc

[root@server ~]# echo $a    

abc            //若赋予变量多个值,最后只输出最后一次赋值的结果,后面的值将会覆盖前面的

[root@server ~]# unset a      //取消自定义变量的定义

[root@server ~]# echo $a     //因为取消变量a的定义,所以输出结果为空

[root@server ~]# a=10

[root@server ~]# echo ${a}RMB     //用{}将变量括起来,就不会将变量与常量混淆

10RMB

######################################################################

  • 环境变量:系统定义好的变量

[root@server ~]# env     //显示所有的环境变量

[root@server ~]# env | grep SHE     //可以结合管道进行查询

SHELL=/bin/bash

GNOME_SHELL_SESSION_MODE=classic

[root@server ~]# set     //查看所有变量

[root@server ~]# abcd=88888888

[root@server ~]# set | grep abcd

abcd=88888888

— 常见环境变量

[root@server ~]# echo $USER

root

[root@server ~]# echo $UID

0

[root@server ~]# echo $HOME

/root

[root@server ~]# echo $SHELL

/bin/bash

— 不常见环境变量

[root@server ~]# echo $PS1     //一级提示符

[\u@\h \W]\$

[root@server ~]# echo $PS2      //二级提示符

>       //换行,在未输完命令的后面加 \

[root@server ~]# echo $PATH     //命令程序存放路径

/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin     //当执行某个命令时,Linux 会依照 PATH 中包含的目录依次搜寻该命令的可执行文件,一旦找到,即正常执行;反之,则提示无法找到该命令。路径用:分开

[root@server opt]# vim test1.sh

#!/bin/bash

echo abc

[root@server opt]# chmod u+x /opt/test1.sh

[root@server opt]# ./test1.sh

abc

[root@server opt]# test1.sh

bash: test1.sh: command not found...

将test1.sh放入环境变量PATH中任意一路径中,以后执行此脚本就不需要加路径,就可以直接执行

[root@server opt]# cp test1.sh /usr/local/sbin/

[root@server opt]# test1.sh

abc

注:若随便修改环境变量PATH,将导致无法找到系统命令

[root@server opt]# PATH=     //将环境变量定义为空,系统将找不到命令

bash: sed: No such file or directory

[root@server opt]# ls

bash: ls: No such file or directory

bash: sed: No such file or directory

[root@server opt]# touch abc

bash: touch: No such file or directory

bash: sed: No such file or directory

########################################################################

  • 位置变量($1   $2   $3 .. ..)

  • 预定义变量($0   $$   $?   $#   $*   $!)

[root@server ~]# cd /opt

[root@server opt]# vim test5.sh

#!/bin/bash

echo $1     //脚本后跟的第一个参数

echo $2     //脚本后跟的第二个参数

echo $3     //脚本后跟的第三个参数

echo $$     //显示当前程序运行时的进程号(进程号为随机的)

echo $#     //显示所有位置变量的个数,下面有三个参数,所以为3

echo $*     //显示所有的位置变量,下面参数为a,b,c,所以输出结果为a b c

echo $?     //显示上一条命令的状态返回值,0是正常;非0是异常

echo $0     //显示执行脚本的名称

echo $!      //显示最后一条放在后台的程序的进程号,无后台进程,所以为空

[root@server opt]# bash test5.sh a b c     //输出结果对应上面脚本的变量

a

b

c

10667

3

a b c

0

test5.sh

(空)

[root@server ~]# sleep 1000 &     //将sleep 1000放到后台执行

[1] 10955     //进程号为10955

[root@server ~]# echo $!     //查看后台进程的进程号

10955

  • 利用位置变量编写创建账户配置密码的脚本(test6.sh)

[root@server ~]# cd /opt

[root@server opt]# vim test6.sh

#!/bin/bash

useradd  $1

echo  $2  |  passwd  --stdin  $1

[root@server opt]# bash test6.sh dc 123456

Changing password for user dc.

passwd: all authentication tokens updated successfully.

#######################################################################

  • 变量的扩展应用

"" :界定范围

''  :界定范围,可以屏蔽特殊符号

``  (反撇号):获取命令的结果,而不是命令本身

$()与``(反撇号)效果一致

[root@server ~]# cd /mnt

[root@server mnt]# touch a b     //创建2个文件

[root@server mnt]# ll

-rw-r--r--. 1 root root 0 Jul 16 07:53 a

-rw-r--r--. 1 root root 0 Jul 16 07:53 b

[root@server mnt]# touch "a  b"     //创建1个文件

[root@server mnt]# ll

-rw-r--r--. 1 root root 0 Jul 16 07:53 a

-rw-r--r--. 1 root root 0 Jul 16 07:53 a  b

-rw-r--r--. 1 root root 0 Jul 16 07:53 b

[root@server mnt]# touch 'c  d'     //创建1个文件

[root@server mnt]# ll

-rw-r--r--. 1 root root 0 Jul 16 07:53 c  d

[root@server ~]# a=10

[root@server ~]# echo $a

10

[root@server ~]# echo "$a"     //显示变量的值(内容)

10

[root@server ~]# echo '$a'     //显示$a,$是特殊符号,功能被屏蔽

$a

[root@server ~]# d=date     //定义变量d,内容是date

[root@server ~]# echo $d

date

[root@server ~]# d=`date`     //定义变量d,内容是date命令执行的结果

[root@server ~]# echo $d

Fri Jul 16 07:58:20 PDT 2021

[root@server ~]# d=$(date)

[root@server ~]# echo $d

Fri Jul 16 07:58:20 PDT 2021

  • 使用read命令从键盘读取变量值

read的基本用法:执行后会等待并接收用户输入,并赋值给变量;可以结合选项[-p]给出提示

  • 优化创建账户配置密码的脚本(test6.sh)

[root@server ~]# cd /opt

[root@server opt]# vim test6.sh

#!/bin/bash

read -p "请输入用户名:" u

useradd $u

read -p "请输入密码:" p

echo $p | passwd --stdin $u

[root@server opt]# bash test6.sh

请输入用户名:zhangsan

请输入密码:123456

Changing password for user zhangsan.

passwd: all authentication tokens updated successfully.

  • stty终端显示控制

stty -echo:关闭回显功能

stty echo:恢复回显功能

  • 优化创建账户配置密码的脚本,使得输入密码是关闭回显功能(test6.sh)

[root@server opt]# vim test6.sh

#!/bin/bash

read -p "请输入用户名:" u

useradd $u

stty -echo

read -p "请输入密码:" p

stty echo

echo $p | passwd --stdin $u

[root@server opt]# bash test6.sh

请输入用户名:lisi

请输入密码:Changing password for user lisi.

passwd: all authentication tokens updated successfully.

  • 局部变量

定义的变量a只能在当前解释器中使用,新开一个解释器后,变量a是未定义的,所以为空

[root@server ~]# a=10         

[root@server ~]# echo $a    

10

[root@server ~]# bash     //开启新解释器(进入子进程)

[root@server ~]# echo $a      //测试,无值,因为a是局部变量

(空)

  • 全局变量——系统将自己定义好的变量(环境变量)发布为全局变量

[root@server ~]# echo $USER

root

[root@server ~]# bash

[root@server ~]# echo $USER

root

  • 局部变量发布为全局变量

export可以将局部变量发布为全局变量

export  变量 ——已经定义了变量

export  变量=值 ——未定义变量    

export  -n  变量 ——取消发布全局变量,变为局部变量

[root@server ~]# a=10

[root@server ~]# export a      //a已经被定义过,对已有变量的变量,发布全局变量

[root@server ~]# echo $a

10

[root@server ~]# bash     //开启新解释器(进入子进程)

[root@server ~]# echo $a     //测试,有值,因为a已经成为全局变量

10

[root@server ~]# exit     //退出新解释器

[root@server ~]# export b=20     //b未被定义过,创建新变量,并发布成全局变量

[root@server ~]# echo $b

20

[root@server ~]# bash     //测试,有值,因为b已经成为全局变量

[root@server ~]# echo $b

20

[root@server ~]# export -n b     //撤销全局变量b,恢复为局部变量

[root@server ~]# bash

[root@server ~]# echo $b     //测试,无值,因为已经撤销全局变量

(空)

注:撤销全局变量必须与发布全局变量在同一个解释器内

##########################################################################

shell中的运算

  • expr命令——调用变量,没有改变变量本身

既有运算的能力,也有显示输出的能力(注:数字,运算符之间都必须有空格)

[root@server ~]# expr 1 + 1

2

[root@server ~]# expr 2 - 1

1

[root@server ~]# expr 2 '*' 2     // * 为特殊字符,指全部,需要屏蔽特殊含义

4

[root@server ~]# expr 2 \* 2

4

[ro    ot@server ~]# expr 4 / 2     //取商(整数)

2

[root@server ~]# expr 10 % 3     //求模,取余数

1

注:

\  :转义符号,屏蔽之后的一个字符的特殊含义

''  :可以屏蔽单引号之间所有字符的特殊含义

[root@server ~]# a=10

[root@server ~]# echo $a

10

[root@server ~]# expr $a + 5

15

[root@server ~]# expr $a + $a

20

  • $[]与$(())——调用变量,没有改变变量本身

乘法操作*无需转义,数字与运算符之间无需空格,引用变量可省略$符号;不会显示结果,可结合echo命令输出

[root@server ~]# echo $[1+1]

2

[root@server ~]# echo $[2-1]

1

[root@server ~]# echo $[2*2]     //无需使用转义字符

4

[root@server ~]# echo $[4/2]

2

[root@server ~]# echo $[5%2]

1

[root@server ~]# a=10

[root@server ~]# echo $[a+10]

20

[root@server ~]# echo $[a*a]

100

  • let命令

可以改变变量本身的值,不显示结果

非主流用法:

[root@server ~]# a=10

[root@server ~]# let a=a+1

[root@server ~]# echo $a

11

[root@server ~]# let a=a*2

[root@server ~]# echo $a

22

主流用法:(建议使用)

[root@server ~]# a=10

[root@server ~]# let a++           //a++(a=a+1)

[root@server ~]# echo $a  

11

[root@server ~]# let a--            //a--(a=a-1)

[root@server ~]# echo $a

10

[root@server ~]# let a+=5          //a+=5(a=a+5)

[root@server ~]# echo $a

15

[root@server ~]# let a-=5              //a-=5(a=a-5)

[root@server ~]# echo $a

10

[root@server ~]# let a*=5             //a*=5(a=a*5)

[root@server ~]# echo $a

50

[root@server ~]# let a/=5             //a/=5(a=a/5)

[root@server ~]# echo $a

10

[root@server ~]# let a%=3             //a%=3(a=a%3)

[root@server ~]# echo $a

1

注:以上三种运算方法,只能整数运算,不支持小数运算

  • bc命令

bc为交互式命令,可以运算小数

[root@server ~]# bc

bc 1.06.95

Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.

This is free software with ABSOLUTELY NO WARRANTY.

For details type `warranty'.

1.1+1.1

2.2

1.1*1.1     //只显示小数点后1位

1.2

10/3       //商只取整数

3

scale=4      //scale定义小数点后显示的位数

10/3

3.3333

quit       //退出

注:bc命令为交互式命令不能直接写入脚本

[root@server ~]# echo "1.1+1.1" | bc       //使用bc进行非交互式计算,并且可以计算小数

2.2

[root@server ~]# echo "10/3" | bc        //不定义小数点后面的长度,默认取整数   

3

[root@server ~]# echo "scale=4;10/3" | bc   //scale定义小数点后面的长度,;代表前后命令的区分   

3.3333

注:若要使用bc写脚本时,必须使用echo结合管道的方式

 


版权声明:本文为N_jw107原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。