【Linux】shell编程1(shell脚本书写格式、脚本中的环境变量、普通变量、自定义环境变量、变量数组、位置变量、状态变量、内置变量、变量扩展)

一、Linux Shell脚本编程入门

1.1 什么是Shell

Shell是Linux上的一个命令解释器。它的作用是解释执行用户输入的命令,然后调用相应的应用程序,命令行中每键入一个命令,Shell就解释执行一条,并将结果展示到命令行窗口中,这种称为交互式的方式。

Shell俗称壳,存在于操作系统的最外层,负责与用户直接对话。把用户的输入解释给操作系统,并将操作系统输出的结果输出给屏幕返回给用户。


1.2 什么是shell脚本

Shell脚本就像早期dos年代的.bat,最简单的功能就是将许多指令汇整在一起,让使用者很容易地 就能够一个操作执行多个命令,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处 理更强大,它提供了数组、循环、条件以及逻辑判断等重要功能,让使用者可以直接以Shell来写程序, 比用其他编程语言编写的程序效率更高,毕竟它使用了Linux/Unix下的命令。

# cat /etc/shells
#查看当前环境下支持的shell

1.3创建第一个Shell脚本

在 Linux 系统中, Shell 脚本(bash Shell 程序) 通常是在编辑器 vi/vim 中编写的,由 UNIX/Linux 命令、 bash Shell 命令、 程序结构控制语句和注释等内容组成。 这里推荐用 Linux 自带的 功能更强的 vim 编辑器来编写, 可以事先做一个别名 alias vi='vim,,并使其永久生效, 这样以后习惯 输人 vi 的读者也就可以直接调用 vim 编辑器了, 设置方法如下:

# echo "alias vi='vim'" >>/etc/profile
# source /etc/profile

1.3.1、脚本开头(第一行)

脚本文件一般以.sh结尾;一个规范的 Shell 脚本在第一行会指出由哪个程序(解释器) 来执行脚本中的内容,这一行内容在 Linux bash 的编程一般为,:

#!/bin/bash

1.3.2、脚本的注释

在Shell脚本中,除了第一行,跟在#后面的内容均为注释内容,注释部分不会当做程序来执行,仅供开发者和使 用者看,注释可以自成一行也可以跟在代码段后面,在我们学习Shell脚本编程时养成注释的好习 惯,方便别人也为了方便自己,例如:


1.3.3、脚本的执行

Shell脚本的执行方法有一下几种:

1、bash script_name或者sh script_name,当脚本没有执行权限时,建议使用此种方法执行脚本,默认情况下LInux不允许文件具有执行权限(从安全上来说,这是一件非常好的事情),所以推荐大家使 用这种方法;

2、./script_name 或者/path/to/script_name,在当前路径或者指定路径下执行脚本,这种方法要求脚本具有执行权限。若没有需要我们给脚本文件增加执行权限。

现在文件没有执行权限

执行脚本显示权限拒绝

修该权限后就可以运行

3、source script_name或者. script_name,了解一下就好。


1.3.4、Shell脚本编写规范

1、指定解释器,通常为

#!/bin/bash
或者
#!/bin/sh

2、增加版本,作者及脚本描述信息等

#Date: 18:00 2018-10-10
#Author: Little Fatty
#Desc: Clean logs
#Version: 1.0
#Email: nebula-tech@163.com

3、脚本注释尽量减少中文

4、Shell脚本的扩展名以.sh结尾

5、成对的符号应该一次写完,然后退格在括号增加内容。如[ ]、{ }、“ ”、``、‘ ’、等等

6、流程控制语句应该先写将格式写完,再添加内容,避免嵌套增多时遗漏。代码缩进让代码内容更

清晰。

if 条件语句
    then
        内容

fi

for
do
       内容
done

二、Shell脚本中的变量

变量为程序或脚本访问内存中的可被修改的一块数据提供 了简单的方式。Linux Shell中的变量可以被指定为任意的数据类型,比如文本字符串或是数值。

#  LittleFatty=" I am LittleFatty "
# echo $LittleFatty

2.1变量的类型

变量可分为两类: 环境变量(全局变量) 和普通变量(局部变量)。

环境变量也可称为全局变量, 可以在创建它们的 Shell 及其派生出来的任意子进程Shell 中使用,环 境变量又可分为自定义环境变量和 bash 内置的环境变量。

普通变量也可称为局部变量, 只能在创建它们的 Shell 函数或 Shell 脚本中使用。 普通变量一般由开 发者在开发脚本程序时创建。


2.1.1常见的环境变量


2.1.2查看环境变量

# set  (输出所有的变量)
# env
# declare 
# typeset

2.2自定义环境变量

如果想要设置环境变量,就需要给变量赋值之后或在设置变量时使用export命令,除了export之外还可以使用declare带-x选项的方法来定义。 我们在当前shell环境定义的变量只在当前环境有效 ; export和declare命令格式如下:

①export 变量名=value
②变量名=value;export 变量名
③declare -x 变量名=value

注:在赋值操作符“=”的周围,不要有任何空格。本地变量定义也需要遵循。


2.2.1当前shell环境变量永久生效

(1)用户的环境变量配置

.bashrc
.bash_profile

(2)全局的环境变量配置 ,所有用户生效;

/etc/profile
/etc/bashrc
/etc/profile.d/

在这三个文件中优先推荐在/etc/bashrc中设置,如果要在登陆后初始化或者显示加载内容,我们可以将写好的脚本文件放在/etc/profile.d/下即可(无需加执行权限) 。


2.2.2设置登录提示的两种方式

第一种:

# vim /etc/motd
# cat /etc/motd

第二种:

在/etc/profile.d/下增加脚本

# cd /etc/profile.d/
# echo "echo hello world" > login.sh

2.2.3用unset取消环境变量

格式:unset 变量名

# env |grep bbb
# a=123
# echo $a
123
# unset a
# echo $a

#

2.2.4环境变量生效顺序

用户登录系统环境变量文件生效顺序

  • /etc/profile

  • /etc/profile.d/

  • .bash_profile

  • .bashrc

  • /etc/bashrc

非交互式登录(不用用户登录)环境变量文件生效顺序 ;

只会加载家目录下.bashrc,/etc/bashrc ;

/etc/bashrc是最后加载的,但也是最先生效的;所以一般定义环境变量定义到这个文件中就可以了。


2.3普通变量

普通变量也叫局部变量或者本地变量,顾名思义,本地环境变量只在定义它们的本地进程中可见Linux系统中默认定义了标准的本地环境变量。目前来说还没有那个命令只显示出本地变量,我们可以使用set命令显示出所有的变量,其中包括执行env显示的全局环境变量,剩下的变量即为本地变量。


2.3.1 自定义本地变量

1.本地变量的赋值

变量名=value
变量名='value'
变量名="value"

2.变量名及赋值要求

变量名一般由字母、数字、下划线组成,要能做到见名知义。

变量的值可以用单引号,双引号或者不加引号,三者含义有所不同。

3.变量定义示例

# a=1
# b='2'
# c="3"
# echo $a $b $c
1 2 3
# echo ${a} ${b} ${c}
1 2 3

输出变量时,若加上单引号,如果引号里有变量则该变量不会被替换,例如:

通过上面例子我们来总结一下,三种不同定义方式的结果

第一种定义变量a的方式是不加任何引号,直接定义内容,当内容为简单的连续数字,字符串等时可 以这样用,例如a=1,a=abc等,不加引号,值里有变量时,会被解析出变量值再一同输出

第二种定义变量b的方式是加了单引号,这种定义的方式的特点是,输出变量的值的时候,引号内的值是什么就输出什么,不会解析,当值中有变量或者命令(命令用反引号)也只会原样输出,这种方式比较适合定义显示纯字符的情况,不希望有解析的场景。

第三种定义变量c的方式是用双引号,这种方式在输出变量的值的时候,会将值中的变量和命令解析后再输出,而不是原样输出,这种方式比较适合希望将变量值中的变量及命令解析出来的场景。加双引号的方式是最常见的定义变量方式。


2.3.2变量值使用一个命令的结果的赋值方法

变量名=`commond` <---此处使用的反引号,Tab键上的符号
变量名=$(commond) <---把命令使用$()括起来

此方式在企业生产场景中很常见,例如以当前日期时间命令的备份压缩等操作。

例如打包备份文件

[root@nebulalinux ~]# echo `date +%F`.tar.gz
2018-11-04.tar.gz
[root@nebulalinux ~]# tar zcf etc_$(date +%F).tar.gz /etc
tar: Removing leading `/' from member names
[root@nebulalinux ~]# ls
etc_2018-11-04.tar.gz

2.4 变量数组

环境变量的一个非常好的特性就是能够当做数组使用,数组是能够保存多个值的变量,数组中的值 既可以分别引用,也可以作为整体引用。

要为某个环境变量设置多个值,只需要将他们列到圆括号内,各个值之间用空格分割

# myvariable=(one two 3 4 5 6 7)
# echo $myvariable
one

显示变量值的时候大家发现并没有将所有的变量值都显示出来,而是只显示了第一个值,要想显示数组的中的值,我们需要使用数值索引号;

echo ${myvariable[1]}

索引的值以0开始,大家要注意,第一个值的索引号是0

显示整个数值的变量,可以用*号通配

# echo ${myvariable[*]}
one two 3 4 5 6 7

2.5 特殊的Shell变量

2.5.1 位置变量

位置变量

作用说明

$0

获取脚本文件名

$n

获取脚本的第n个参数 如果n>9, ${10}

$#

获取当前脚本的参数总个数

$*

获取脚本所有传递的参数,把参数当作一个整体字符串,如果不加引号结果与$@相同

$@

获取脚本所有传递的参数,把参数当作独立的字符串

在Shell中存在一些特殊的环境变量,例如 #,#*,我们称为位置参数变量,要给命令,脚本等传递参数时,就需要在Shell脚本中使用位置参数变量;

在执行脚本的时候,脚本后面的值可以当作脚本的参数来执行;

# vi mytest1.sh

#!/bin/bash
echo "当前脚本文件名:$0"
n=1

echo "使用\$@的参数列表为:$@"
echo "总共有$#个参数"
for i in "$@"
do
      echo "第$n个参数的值是:$i"
      let n+=1
done

# bash  mytest1.sh 1 2 3 4 5
# vi mytest2.sh

#!/bin/bash
echo "当前脚本文件名:$0"
n=1

echo "使用\$*的参数列表为:$*"
echo "总共有$#个参数"
for i in "$*"
do
      echo "第$n个参数的值是:$i"
      let n+=1
done

# bash  mytest2.sh 1 2 3 4 5
#vi mytest3.sh

#!/bin/bash
echo "当前脚本文件名:$0"
n=1

echo "使用\$*的参数列表为:$*"
echo "总共有$#个参数"
for i in $*
do
        echo "第$n个参数的值是:$i"
        let n+=1
done
# bash  mytest3.sh 1 2 3 4 5

总结$@ "$*" $*的区别:

$@将传递的参数看作一个一个的的单个字符串;

"$*"将传递的参数看作是一个整体;

$*$@一样,将传递的参数看作一个一个的的单个字符串;


2.5.2 状态变量

变量功能演示 :

[root@nebulalinux ~]# pwd
/root
[root@nebulalinux ~]# echo $?
0 #<---0表示执行成功
[root@nebulalinux ~]# cmd
-bash: cmd: command not found
[root@nebulalinux ~]# echo $?
127 #<---127表示命令执行失败
[root@nebulalinux ~]# echo $$
21457 #<---显示当前shell进程号
[root@nebulalinux ~]# top & #<-----在后台执行
[1] 21475
[root@nebulalinux ~]# echo $!
21475 #<---显示上一个后台工作的进程的进程号
[1]+ Stopped top
[root@nebulalinux ~]# ls -ld /root/
dr-xr-x---. 2 root root 4096 Oct 12 05:36 /root/
[root@nebulalinux ~]# echo $_
/root/ #<---获取上个命令的最后一个参数
[root@nebulalinux ~]#

2.5.3内置命令

Shell中包含了一些内置命令,如echo,printf,export,read,shift等 ;

1.echo命令用于在屏幕上输出数据,常用选项有:

[root@nebulalinux ~]# echo hello;echo world
hello
world
[root@nebulalinux ~]# echo -n hello;echo world
helloworld
[root@nebulalinux ~]# echo "hello\tworld\nhello\tworld"
hello\tworld\nhello\tworld
[root@nebulalinux ~]# echo -e "hello\tworld\nhello\tworld"
hello world
hello world
[root@nebulalinux ~]# echo -e "hello\vworld\vhello\vworld"
hello
world
hello
world
[root@nebulalinux ~]# echo -e "hello \bworld"
helloworld
#printf功能和echo类似

2.exec命令

exec命令可以在不创建子进程的情况下去执行指定命令,并在命令执行结束后进程终止;

[root@nebulalinux ~]# su - nebula
hello world
[nebula@nebulalinux ~]$ exec date
Sun Nov 4 13:16:24 EST 2018
[root@nebulalinux ~]#

3.read命令

从标准输入中读取字符串信息,传给Shell内部定义的变量;

语法格式:read [选项] 变量名

选项:

  • -t:等待时间,

  • -p:设置提示信息

[root@nebulalinux ~]# read -t 10 -p "please input one number: " num
please input one number: 1
[root@nebulalinux ~]# echo $num
1

4.shift命令

shift语句会重新命名所有的位置参数;每使用一次shift,所有位置参数依次向左诺一位,并且位置参数$#会减一。


2.6 Shell变量扩展

表达式

说明

${parameter:-word}

如果parameter的变量值为空或者未赋值,则会返回word字符串代替变 量值

${parameter:=word}

如果parameter的变量值为空或者未赋值,则设置这个变量值为word, 返回值也是word

${parameter:?word}

如果parameter的变量值为空或者未赋值,那么word字符串会被当做标 准错误输出,否则输出变量的值

${parameter:+word}

如果parameter的变量值为空或者未赋值,则输出空值,否则word字 符串将被替代变量的值

2.6.1 ${parameter:-word}功能实践

[root@nebulalinux03 ~]# echo $test #变量未设置输出为空
[root@nebulalinux03 ~]# res=${test:-unset} #使用特殊变量
[root@nebulalinux03 ~]# echo $res 打印res,返回unset
unset
[root@nebulalinux03 ~]#
#当变量test没有定义值时,就返回变量结尾设置的unset字符串
#可以用来判断变量是否已定义

2.6.2 ${parameter:=word}功能实践

[root@nebulalinux03 ~]# unset res
[root@nebulalinux03 ~]# echo $res
[root@nebulalinux03 ~]# unset test
[root@nebulalinux03 ~]# echo $test
[root@nebulalinux03 ~]# res=${test:=unset}
[root@nebulalinux03 ~]# echo $res
unset
[root@nebulalinux03 ~]# echo $test
unset
#test原本没有定义,现在已经被赋值unset
[root@nebulalinux03 ~]#
#当变量res值中的变量test值没有定义时,会给变量res赋值“:=”后面的值,同时会把“:=”后面的值赋
值给变量test
#可以用来解决变量没有定义的问题,并确保没有定义的变量的始终有值

2.6.3 ${parameter:?word}功能实践

[root@nebulalinux03 ~]# unset test
[root@nebulalinux03 ~]# echo ${test:? not defined}
-bash: test: not defined
[root@nebulalinux03 ~]# echo ${test? not defined}
-bash: test: not defined
[root@nebulalinux03 ~]# test=hello
[root@nebulalinux03 ~]# echo ${test:? not defined}
hello
[root@nebulalinux03 ~]# echo ${test? not defined}
hello
[root@nebulalinux03 ~]# unset test
[root@nebulalinux03 ~]# echo ${test? not defined}
-bash: test: not defined
[root@nebulalinux03 ~]#
#用来设定由于由于变量未定义而报错的内容

2.6.4 ${parameter:+word}功能实践

[root@nebulalinux03 ~]# res=${test:+replace}
[root@nebulalinux03 ~]# echo $res
[root@nebulalinux03 ~]# test=hello
[root@nebulalinux03 ~]# res=${test:+replace}
[root@nebulalinux03 ~]# echo $res
replace
[root@nebulalinux03 ~]#
#测试变量是否存在,如果变量值为replace,则证明变量test有值

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LKsTaRt~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值