赞
踩
Shell是Linux上的一个命令解释器。它的作用是解释执行用户输入的命令,然后调用相应的应用程序,命令行中每键入一个命令,Shell就解释执行一条,并将结果展示到命令行窗口中,这种称为交互式的方式。
Shell俗称壳,存在于操作系统的最外层,负责与用户直接对话。把用户的输入解释给操作系统,并将操作系统输出的结果输出给屏幕返回给用户。
Shell脚本就像早期dos年代的.bat,最简单的功能就是将许多指令汇整在一起,让使用者很容易地 就能够一个操作执行多个命令,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处 理更强大,它提供了数组、循环、条件以及逻辑判断等重要功能,让使用者可以直接以Shell来写程序, 比用其他编程语言编写的程序效率更高,毕竟它使用了Linux/Unix下的命令。
- # cat /etc/shells
- #查看当前环境下支持的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
脚本文件一般以.sh结尾;一个规范的 Shell 脚本在第一行会指出由哪个程序(解释器) 来执行脚本中的内容,这一行内容在 Linux bash 的编程一般为,:
#!/bin/bash
在Shell脚本中,除了第一行,跟在#后面的内容均为注释内容,注释部分不会当做程序来执行,仅供开发者和使 用者看,注释可以自成一行也可以跟在代码段后面,在我们学习Shell脚本编程时养成注释的好习 惯,方便别人也为了方便自己,例如:
Shell脚本的执行方法有一下几种:
1、bash script_name或者sh script_name,当脚本没有执行权限时,建议使用此种方法执行脚本,默认情况下LInux不允许文件具有执行权限(从安全上来说,这是一件非常好的事情),所以推荐大家使 用这种方法;
2、./script_name 或者/path/to/script_name,在当前路径或者指定路径下执行脚本,这种方法要求脚本具有执行权限。若没有需要我们给脚本文件增加执行权限。
现在文件没有执行权限
执行脚本显示权限拒绝
修该权限后就可以运行
3、source script_name或者. script_name,了解一下就好。
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
变量为程序或脚本访问内存中的可被修改的一块数据提供 了简单的方式。Linux Shell中的变量可以被指定为任意的数据类型,比如文本字符串或是数值。
- # LittleFatty=" I am LittleFatty "
- # echo $LittleFatty
变量可分为两类: 环境变量(全局变量) 和普通变量(局部变量)。
环境变量也可称为全局变量, 可以在创建它们的 Shell 及其派生出来的任意子进程Shell 中使用,环 境变量又可分为自定义环境变量和 bash 内置的环境变量。
普通变量也可称为局部变量, 只能在创建它们的 Shell 函数或 Shell 脚本中使用。 普通变量一般由开 发者在开发脚本程序时创建。
- # set (输出所有的变量)
- # env
- # declare
- # typeset
如果想要设置环境变量,就需要给变量赋值之后或在设置变量时使用export命令,除了export之外还可以使用declare带-x选项的方法来定义。 我们在当前shell环境定义的变量只在当前环境有效 ; export和declare命令格式如下:
- ①export 变量名=value
- ②变量名=value;export 变量名
- ③declare -x 变量名=value
注:在赋值操作符“=”的周围,不要有任何空格。本地变量定义也需要遵循。
(1)用户的环境变量配置
- .bashrc
- .bash_profile
(2)全局的环境变量配置 ,所有用户生效;
- /etc/profile
- /etc/bashrc
- /etc/profile.d/
在这三个文件中优先推荐在/etc/bashrc中设置,如果要在登陆后初始化或者显示加载内容,我们可以将写好的脚本文件放在/etc/profile.d/下即可(无需加执行权限) 。
第一种:
- # vim /etc/motd
- # cat /etc/motd
第二种:
在/etc/profile.d/下增加脚本
- # cd /etc/profile.d/
- # echo "echo hello world" > login.sh
格式:unset 变量名
- # env |grep bbb
- # a=123
- # echo $a
- 123
- # unset a
- # echo $a
-
- #
用户登录系统环境变量文件生效顺序
/etc/profile
/etc/profile.d/
.bash_profile
.bashrc
/etc/bashrc
非交互式登录(不用用户登录)环境变量文件生效顺序 ;
只会加载家目录下.bashrc,/etc/bashrc ;
/etc/bashrc是最后加载的,但也是最先生效的;所以一般定义环境变量定义到这个文件中就可以了。
普通变量也叫局部变量或者本地变量,顾名思义,本地环境变量只在定义它们的本地进程中可见Linux系统中默认定义了标准的本地环境变量。目前来说还没有那个命令只显示出本地变量,我们可以使用set命令显示出所有的变量,其中包括执行env显示的全局环境变量,剩下的变量即为本地变量。
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的方式是用双引号,这种方式在输出变量的值的时候,会将值中的变量和命令解析后再输出,而不是原样输出,这种方式比较适合希望将变量值中的变量及命令解析出来的场景。加双引号的方式是最常见的定义变量方式。
- 变量名=`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
环境变量的一个非常好的特性就是能够当做数组使用,数组是能够保存多个值的变量,数组中的值 既可以分别引用,也可以作为整体引用。
要为某个环境变量设置多个值,只需要将他们列到圆括号内,各个值之间用空格分割
- # 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
位置变量 | 作用说明 |
$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
总结:$@ "$*" $*的区别:
$@将传递的参数看作一个一个的的单个字符串;
"$*"将传递的参数看作是一个整体;
$*和$@一样,将传递的参数看作一个一个的的单个字符串;
变量功能演示 :
- [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 ~]#

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,所有位置参数依次向左诺一位,并且位置参数$#会减一。
表达式 | 说明 |
${parameter:-word} | 如果parameter的变量值为空或者未赋值,则会返回word字符串代替变 量值 |
${parameter:=word} | 如果parameter的变量值为空或者未赋值,则设置这个变量值为word, 返回值也是word |
${parameter:?word} | 如果parameter的变量值为空或者未赋值,那么word字符串会被当做标 准错误输出,否则输出变量的值 |
${parameter:+word} | 如果parameter的变量值为空或者未赋值,则输出空值,否则word字 符串将被替代变量的值 |
- [root@nebulalinux03 ~]# echo $test #变量未设置输出为空
- [root@nebulalinux03 ~]# res=${test:-unset} #使用特殊变量
- [root@nebulalinux03 ~]# echo $res 打印res,返回unset
- unset
- [root@nebulalinux03 ~]#
- #当变量test没有定义值时,就返回变量结尾设置的unset字符串
- #可以用来判断变量是否已定义
- [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
- #可以用来解决变量没有定义的问题,并确保没有定义的变量的始终有值
- [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 ~]#
- #用来设定由于由于变量未定义而报错的内容
- [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有值
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。