将自己之前的 shell 脚本笔记搬到 segmentfault,顺带复习一下 shell 基础。2019-1-26
shell 脚本介绍
Shell 介绍 Shell 是一个命令解释器,作用是解释执行用户输入的命令程序等,用户每输入一条命令,Shell 就执行解释一条。这种从键盘输入命令就可以得到回应的方式叫做交互的方式。
Shell 存在于操作系统的最外层,负责与用户直接对话,把用户的输入解释给操作系统,并处理各种操作系统的输出结果,然后输出到屏幕给用户。
Shell 脚本当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行,这个文件就叫做 Shell 脚本。Shell 脚本很适合用于处理纯文本类型的数据,而 Linux 系统中几乎所有的配置文件,日志文件(NFS,Rsync,Httpd,Nginx,LVS 等),以及绝大多数的启动文件都是纯文本类型的文件。因此,学好 shell 语言,就可以利用它在 linux 系统中发挥巨大的作业。
查看 CentOS 系统默认的 Shell
[root@moli_linux1 ~]# echo $SHELL
/bin/bash
[root@moli_linux1 ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
Shell 脚本的创建和执行
Shell 脚本的创建一个规范的 Shell 脚本在第一行会指出由那个程序(解释器)来执行脚本的内容,这一行内容在 Linux bash 编程中一般为:
#!/bin/bash
或者
#!/bin/sh
注意:这一行必须位于每个脚本顶端的第一行,如果不是第一行则为脚本注释行。且 shell 脚本文件的后缀名通常以.sh 结尾。
Shell 脚本的执行
1. bash script-name(脚本的路径名字) 或者 sh script-name:这是当脚本文件没有可执行权限时常用的放法 2. path/script-name 或者./script-name: 指在当前路径下执行脚本(脚本需要有可执行权限)。即需要将脚本文件的权限先修改为可执行,chmod +xscript-name。然后通过脚本的绝对路径和相对路径就可以直接执行脚本。
shell 脚本中的变量
什么是变量变量是暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中,通过正确地调用内存空间中变量的名字就可以取出与变量对应的数据。CentOS 中变量的定义直接由一个赋值符号 = 就可以创建一个变量,而 echo 命令类似于其他语言的 print 命令,打印这个变量的值。
[root@moli_linux1 ~] name=”laowan” #定义一个变量
[root@moli_linux1 ~] echo $name #打印这个变量的值
laowan
[root@moli_linux1 ~] age=14
[root@moli_linux1 ~] echo $age
14
shell 变量的特性默认情况下,在 bash shell 中是不会区分变量类型的。变量类型变量分为:环境变量(全局变量)和普通变量(局部变量)环境变量可以在创建它们的 shell 以及其派生出来的任意子进程 shell 中使用。环境变量又分为自定义环境变量和 bash 内置的环境变量。普通变量只能在创建它们的 shell 函数或 shell 脚本中使用。提示:有三个命令可以查看系统中变量的值:set、env、declare。
set 命令输出所有的变量;
env 只显示全局变量;
declare 命令输出所有的变量,函数,整数和已经导出的变量。
set - o 命令显示 bash shell 的所有参数配置信息。
环境变量的定义上面定义一个变量是在一个 shell 中直接使用赋值符号对这个变量进行创建,但是当打开一个新的子 shell,打印这个变量却不能打印出来。这是因为我们创建的变量是一个普通变量,若想在其他子 shell 中使用这个变量,需要将这个变量设置为全局变量。而定义一个全局变量的方法如下:
export 变量名 =value
或者
declare -x 变量名 =value
第二个方法是将变量名添加到环境变量文件 /etc/profile
编辑环境配置文件
vim /etc/profile
在文件最后面添加
export name=”laowan”
保存,退出。重新加载文件
source /etc/profile
打印变量的值
echo $name
laowan
而 CentOS 中,全局环境变量的配置文件有三个,分别是:
/etc.profile
/etc/bashrc
/etc/profile.d #这是一个目录
当用户登录 Linux 系统时,首先会先加载 /etc/profile 全局环境变量文件,这是 Linux 系统默认的 Shell 主配置文件,其次会执行 /etc/profile.d 下的脚本文件,要做重启 Linux 系统后初始化或者显示某些内容,只需要把脚本文件放在 /etc/progile.d 下即可,最后才会执行 bashrc 文件。
设置登录提示符 Linux 中可以设置登录之后,或者远程连接服务器打开的 shell 中显示登录提示符。设置登录提示内容的文件是 /etc/motd,编辑这个文件就可以设置每次登录提示的内容。例如:
[root@moli_linux1 ~]# cat /etc/motd
welcome to my Linux Server!
打开一个新的 shell
Connecting to 192.168.30.3:22…
Connection established.
To escape to local shell, press ‘Ctrl+Alt+]’.
WARNING! The remote SSH server rejected X11 forwarding request.
Last login: Sat Jan 26 19:35:54 2019 from 192.168.30.1
welcome to my Linux Server!
可以看到登录提示符。
定义变量不加单引号和双引号,加单引号,加双引号的区别
[root@moli_linux1 ~] a=10
[root@moli_linux1 ~] b=10-$a
[root@moli_linux1 ~] c=’100-$a’
[root@moli_linux1 ~] d=”100-$a”
[root@moli_linux1 ~] echo $a
10
[root@moli_linux1 ~] echo $b
10-10
[root@moli_linux1 ~] echo $c
100-$a
[root@moli_linux1 ~] echo $d
100-10
第一种定义 b 变量的方式,当内容为简单连续的数字,字符串,路径名时,可以这样用,不加引号时,值里有变量的会被解析后输出。第二种定义 c 的变量有加单引号,这样输出变量时单引号里面内容是什么就是什么,即使有变量和命令也是直接输出。第三种定义 d 变量的方式加了双引号,这种输出变量内容时引号里的变量以及命令会经过解析后再输出内容,这种方式比较适合字符串中附带有变量以及命令且想将其解析后再输出的变量定义。
取消变量取消变量使用 unset 命令,注意要取消的变量之前不用添加 $ 符号。
[root@moli_linux1 ~] a=100
[root@moli_linux1 ~] echo $a
100
[root@moli_linux1 ~] unset a
[root@moli_linux1 ~] echo $a #可以看到这个变量的为空
[root@moli_linux1 ~]#
将一个命令的结果赋值给一个新的变量生产环境中把命令的结果作为变量的内容进行赋值的方法在脚本开发时很常见。有两个方法可以实现。
变量名 =$(命令)
或者:
变量名 =` 命令 `
[root@moli_linux1 ~] ls
192.168.229 anaconda-ks.cfg git_data server shell-100 test-find
[root@moli_linux1 ~] file=$(ls)
[root@moli_linux1 ~] echo $file
192.168.229 anaconda-ks.cfg git_data server shell-100 test-find
[root@moli_linux1 ~] file2=`ls`
[root@moli_linux1 ~] echo $file2
192.168.229 anaconda-ks.cfg git_data server shell-100 test-find
Shell 中的特殊变量
shell 中特殊位置参数变量要从命令行,函数或脚本执行等处传递参数时,就要在 shell 脚本中使用位置参数变量。
$0:获取当前执行的 shell 脚本的文件名,如果执行脚本包含了路径,那么就包括脚本路径
$1:获得当前执行的 shell 脚本的第 n 个参数值,n=1…….9,当 n 为 0 时表示脚本的文件名,当 n 大于 9 时,则用大括号括起来,例如 $(10),接的参数以空格隔开
$#:获取当前执行的 shell 脚本后面接的参数的总个数
$*:获取当前 Shell 脚本所有传参的参数,不加引号和 $@相同,如果给 $* 加上双引号,例如“$*”,则表示将所有的参数视为单个字符串,相当于“$1$2$3”
#@:获取当前 shell 脚本所有传参的参数,不加引号和 $* 相同;如果给 $@加上双引号,例如:“$@”,则表示将所有的参数视为不同独立的字符串,相当于“$1″,”$2″.”$3”…. 这是将多参数传递给其他程序的最佳方式。
示例 1,特殊位置变量 $1
[root@moli_linux1 script] cat test.sh
#!/bin/bash
echo $1 #脚本的功能是打印脚本传递的第一个参数的值
[root@moli_linux1 script] sh test.sh laowan #传入一个字符串参数,赋值给 $1
laowan
[root@moli_linux1 script] sh test.sh laowan xiaoming #传入多个参数,但脚本不会接收多个参数,因此只输出第一个参数的值
laowan
[root@moli_linux1 script] sh test.sh “I am laowan” #用双引号括起来代表一个参数
I am laowan
示例 2,特殊位置变量 $1,$2,$3….${10}
[root@moli_linux1 script] echo \${1..15} > test2.sh
[root@moli_linux1 script] cat test2.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@moli_linux1 script] sh test2.sh {a..z} #传入 26 个字母 a~z,作为 26 个参数
a b c d e f g h i a0 a1 a2 a3 a4 a5 #位置参数的数字大于 9 后,输出内容就不对了
[root@moli_linux1 script] vim test2.sh
[root@moli_linux1 script] cat test2.sh
#!/bin/bash
#位置参数的数字大于 9 时,需要用大括号将数字括起来
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@moli_linux1 script] sh test2.sh {a..z}
a b c d e f g h i j k l m n o #大于 9 的数字加上大括号后显示正确的内容
示例 3,特殊变量 $0– 获取脚本的名称以及路径:
[root@moli_linux1 shell_test] cat 05-getName.sh
#!/bin/bash
echo $0
[root@moli_linux1 shell_test] sh 05-getName.sh
05-getName.sh