您的位置:首页 > 运维架构 > Shell

Shell脚本的基本介绍

2017-08-01 17:05 281 查看

1、shell概念:

一种壳层与命令行界面,是Unix操作系统下传统的用户和计算机的交互界面。第一个用户直接输入命令来执行各种各样的任务。普通意义上的shell就是可以接受用户输入命令的程序。它之所以被称作shell是因为它隐藏了操作系统低层的细节。


2、变量:

强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误
弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用


(1)本地变量:生效范围为当前shell进程;对当前shell之外的其他shell进程及其子进程无效;


变量赋值:

name=‘NAME’

名命变量规则:
(1)不能使程序中的保留字:例如if, for
(2)只能使用数字、字母及下划线,且不能以数字开头
(3)见名知义
(4)统一命名规则:驼峰命名法
引用变量名的方式:
(1)可以直接字符串:name=’NAME‘
(2)变量引用:name="$NAME";
对于变量引用来说对单引号和双引号是有点区别的:
"":弱引用,其中的变量引用会被替换为变量值;
'':强引用,其中的变量引用不会被替换成变量值;而保持原来的字符串;
(3)命令引用:name=`COMMAND`
注意:如果引用的变量为文件有多行时,将双引号显示多行;不加显示一行输出;


示例: name=
cat /etc/passwd


echo nameecho“name”

注意:建议不用本地变量时,要使用命令unset撤销;

(2)环境变量:生效范围为当前shell进程及其子进程;
变量的声明、赋值:
export name=VALUE
declare -x name=VALUE
变量引用:${name}
查看所有的环境变量:
env
printenv
export
declare -x


(3)只读变量:只能声明,但不能修改和删除,如果想要撤销,退出重新登录即可;
declare -r name=VALUE
readonly name=VALUE
查看:readonly -p
注意:如果设置某些变量可以加括号,只在括号区域内有效;
示例:name=mage;(echo $name;name=wang;echo $name)


(4)位置变量:在脚本代码中调用通过命令行传递给脚本参数;
$$:显示进程ID号;
$@:显示全部参数,全部参数为独立的字符串;
$*:显示全部参数,全部参数为一个字符串;
$@和$*用双引号引起来是有区别的。
$#:传递给脚本的参数个数;
$0:显示当前文件名称;
如果取基名:basename $0

set命令:
set 显示所有的命令;
unset NAME:取消变量;


3、脚本的基本格式:

脚本是命令的堆砌构成;
格式:首行shebang机制:如
#/bin/bash
#/bin/csh
#/bin/python
#!/bin/perl
脚本的规范:脚本代码开头约定
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明
创建脚本:
1、创建一个脚本;
2、对脚步付执行权限;
(1)chmod +x file.sh
(2)/path/file.sh
(3)source /path/file.sh source建议不要使用,执行脚本是会生效当前环境中的变量;
脚本测试:
检测脚本中的语法错误:bash -n /path/to/some_script
调试执行:bash -x /paht/to/some_path


4、退出状态返回值

通常如果我们执行的命令是正确的,系统默认的状态返回值为0,当我们执行的命令错误是系统会返回一个非零的数,进行报错;
[root@centos7 ~]#ls /etc/passwd
/etc/passwd
[root@centos7 ~]#echo $?
0                                  #当我们执行命令正确时显示
[root@centos7 ~]#ll /etc/pss
ls: cannot access /etc/pss: No such file or directory
[root@centos7 ~]#echo $?
2                                  #当执行命令错误是显示;
状态返回值在脚本的作用是挺大的,当我们执行完命令想退出时,我们可以自己定义状态返回值;exit 100
状态返回值的范围:0-255之间。通常系统返回的状态值有它的本身意义,直接看到返回值可以判断是什么错误。


注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字。

注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码。

注意:退出状态码在小括号内,相当于打开一个子进程,退出子进程。

5、算数运算

有些时候我们需要运行一些运算:
(1)let sum = a+b
id++, id--  variable post-increment, post-decrement 先赋值后增加或减少
[root@centos7
4000
~]#j=0
[root@centos7 ~]#a=1
[root@centos7 ~]#let j=a++
[root@centos7 ~]#echo $j
1
[root@centos7 ~]#echo $a
2

++id, --id  variable pre-increment, pre-decrement   先增加或减少后赋值
[root@centos7 ~]#j=0
[root@centos7 ~]#a=1
[root@centos7 ~]#let j=++a
[root@centos7 ~]#echo $j
2
[root@centos7 ~]#echo $a
2
(2)$[a+b]
[root@centos7 ~]#a=3
[root@centos7 ~]#b=5
[root@centos7 ~]#echo $[a+b]
8
[]里面可以加$也可以不用加;
(3)$(())
[root@centos7 ~]#echo $((a+b))
8
(4)declare -i var = 数值    声明变量
[root@centos7 scripts]#declare -i d
[root@centos7 scripts]#d=100
[root@centos7 scripts]#declare -i e
[root@centos7 scripts]#e=200
[root@centos7 scripts]#declare -i x
[root@centos7 scripts]#x=d+e
[root@centos7 scripts]#echo $x
300
注意:声明过的变量可以自动识别数字相加。

(5)expr
var=$(expr arg1 arg2 arg3 ...) 每个参数之间必须有空格;*运算需要转义
$;可以利用此命令判断变量是否整数;
[root@centos7 ~]#expr 0 + 0
[root@centos7 ~]#echo $?
[root@centos7 ~]#1
如果执行结果为0,执行返回码为1;
注意:利用expr命令可以判断变量是否为非零的整数。

(6)echo '算数表达式' |bc
[root@centos7 ~]#echo 100+29 |bc
129


6、逻辑运算

(1)1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0
规律:与1相与的数为它本身,与0相与的数是0.
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
(2)短路&&、短路或||和异或^
短路&&
COMMAND1 && COMMAND2 && ...
当第一个COMMAND执行成功才能执行下一条命令。如果执行不成功则退出。
短路||
COMMAND1 || COMMAND2 ||...
当第一个命令执行成功,后续的命令不再执行;如果第一个命令执行错误,则执行下一条命令。
异或^
10101010  a
11100010  b
01011000  c
异或中两个值相同为假,不同为真。
利用这个特性我们可以数字交换如:
[root@centos7 scripts]#a=10;b=20;a=$[a^b];b=$[a^b];a=$[a^b];echo $a;echo $b
20
10
[root@centos7 scripts]#a=10;b=20;c=$[a^b];b=$[c^b];a=$[c^b];echo $a;echo $b #上述相当于产生一个中间值c,然后与中间值相与就得到了结果;
20
10


7、条件测试

通常在脚本中我们会通过一些测试命令判断字符串、文件的类型、是否有执行权限、文件是否有内容等,需要我们使用测试命令去实现。
test EXPERSSION
[ EXPERSSION ]
[[ EXPERSSION ]]   此表达式支持正则表达式
注意:experssion 必须与中括号有空白字符。
格式:
长格式的例子:
test "$A" == "$B" && echo "Strings are equal" test “$A” -eq “$B” && echo "Integers are equal"
简写格式的例子:
[ "$A" == "$B" ] && echo "Strings are equal" [ "$A" -eq "$B" ] && echo "Integers are equal"
变量建议加上引号;测试时加上引号,才是变量,不加引号相当于字符串。
(1)数值测试
arg1 OP arg2   Arithmetic tests.
OP is one of
-eq 等于
-ne 不等于
-lt 小于
-le 小于等于
-gt 大于
-ge 大于等于
(2)字符串测试
-z STRING   True if string is empty.  字符串是否为空,空位真,不空为假。
-n STRING   True if string is not empty. 字符串是否为不空,不空为真,空为假。
STRING1 = STRING2  True if the strings are equal. 字符串是否相等。
STRING1 != STRING2 True if the strings are not equal. 字符串是否不等。
STRING1 =~ STRING2    左侧字符串是否能够被右侧的PATTERN所匹配,支持正则表达式。一般使用[[]]进行判断。
建议,测试条件都使用引号引起来。
(3)bash文件的测试
判断文件是否存在:
-s FILE        True if file exists and is not empty. 判断文件存在并且不是空

判断文件的类型:
-a FILE        True if file exists.  判断文件是否存在相当于-e选项;
-b FILE        True if file is block special. 判断文件是否为块设备;
-c FILE        True if file is character special. 判断文件是否为字符设备
-e FILE        True if file exists. 判断文件是否存在;
-f FILE        True if file exists and is a regular file. 判断是否为普通文件;
-h FILE        True if file is a symbolic link. 判断是否链接文件,相当于-L
-L FILE        True if file is a symbolic link. 判断是否链接文件,相当于-h
-p FILE        True if file is a named pipe. 判断是否文管道文件
-S FILE        True if file is a socket. 判断文件是否为套接字文件

判断执行权限:
-w FILE        True if the file is writable by you.
-r FILE        True if file is readable by you.
-x FILE        True if the file is executable by you.

判断当前用户是否为属主或属组:
-G FILE        True if the file is effectively owned by your group.
-O FILE        True if the file is effectively owned by you.

判断特殊权限
-g FILE        True if file is set-group-id.
-u FILE        True if the file is set-user-id.
-k FILE        True if file has its `sticky' bit set.

-N FILE        True if the file has been modified since it was last read.


注意:判断文件时,实现要判断文件是否为链接文件,如果不判断的还链接文件显示的是指向文件的文件类型。

双目测试:
FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode  检测硬链接;
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
如果软连接也会显示
逻辑运算
第一种方式:
COMMAND1&&COMMAND2
COMMAND1||COMMAND2
!COMMAND
第二种方式:
EXPRESSIONG1 -a EXPERSION2
EXPRESSIONG1 -o EXPERSION2
!EXPRESSIONG


8、read命令

有时候我们写脚本需要提示信息给用户,让用户理解要输入什么内容;
-p 指定要显示的提示;
-s 静默输入,一般用于密码
-n N 指定输入的字符长度;
-d ‘字符’ 输入结束符;
-t N TIMEOUT为N秒
工作原理:read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词分配给最后一个变量。


9、命令如何展开命令行

10、防止扩展

在一些命令中某些符号我们需要用反斜线转义。
[root@centos7 ~]#echo $a
20
[root@centos7 ~]#echo \a
a
有时候也会加单引号、双引号防止扩展
单引号是强引用;
双引号是弱引用; 下面是他们的区别:
[root@centos7 ~]#echo '$a'
$a
[root@centos7 ~]#echo "$a"
20
特殊情况:
$(美元符号)  -  变量扩展
`(反引号)  -  命令替换
\(反斜线)  -  禁止单个字符扩展
!(叹号)  -  历史命令替换


11、bash的配置文件

交互式登录:
(1)直接通过终端输入账户密码登录
(2)使用“su - USERNAME”切换用户
执行顺序: /etc/profile --> /etc/profile.d/*.sh -->~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录:
(1)su USERNAME
(2)图形界面下打开的终端
(3)执行脚本
(4)任何其他的bash示例
执行顺序:~/.bashrc --> ~/.bash_profile --> /etc/profile.d/*.sh
全局配置文件
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置文件
~/.bashrc
功用:
1、定义别名和函数
2、定义本地变量
~/.bash_profile
功用:
1、用于定义环境变量
2、运行命令或脚本
profile类:为交换式登录的shell提供配置;
bashrc类:为非交互式和交互式登录的shell提供配置;
修改后的文件不能立马生效,需要通过以下两种方法实现:
1、重新启动shell进程;
2、source 命令执行。

bash退出任务,保存在~/.bash_logout文件中。用于创建自动备份和清除临时文件。在退出登录shell时运行。


12、$-变量

h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
i:interactive-comments,包含这个选项说明当前的 shell是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的。
m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell 脚本 linux