#!/bin/bash
#My first shell script
#Hello world!
echo "Hello world!"
解释:
第一行:#!/bin/bash
指定运行这个脚本的解释器是/bin/bash
‘#’表示这一行是注释,然后跟了一个!表示这一个非注释!!!
第二,三行:注释信息,标明这个脚本的功能
当写一个比较大的脚本时,如果没有一个好的注释,那么也就没有人都能够看懂其中的意思了
第四行:脚本的实现(输入平时在shell中输入的命令即可)
脚本执行方式:
1,对文件添加可执行权限,然后用绝对路经和相对路径
chmod + x first.sh
/home/lu/myshell/first.sh
或者./first.sh
2,使用bash
bash firsh.sh
注:绝对路径和相对路径需要文件具有执行权限(在企业,不推荐使用,不安全)
bash 不需要可执行权限(推荐使用)
shell变量
定义:可以存放一个可变的值的空间
默认情况下Linux中可以将每个shell看成不同的执行环境,所以相同的变量名,在不同的执行环境中变量值是不同的
变量的分类:自定义变量,环境变量,位置变量,预定义变量
变量的输出:echo $[变量名] # $是引用变量的特殊字符(固定格式)
变量的介绍:(注意,shell中区分大小写)
自定义变量:用户根据自己的环境,自己定义的变量,(最简单的变量)
声明格式:变量名=变量值
注意:=左右两边不要有空格;
变量名只能以字母和下划线开头,且名称中不能出现特殊符号
特殊符号:+-*/,.`\?%等
举例:1,定义变量并输出
2,一起调用两个变量
[lu@bogon ~]$ xiaogan=123
[lu@bogon ~]$ echo $xiaogan
123
[lu@bogon ~]$ xg=111
[lu@bogon ~]$ echo $xg
111
[lu@bogon ~]$ echo $xg $xiaogan
111 123
3,{}的使用
[lu@bogon ~]$ echo $xiaogan
123
[lu@bogon ~]$ abc=$xiaogannihao
[lu@bogon ~]$ echo $?
0
[lu@bogon ~]$ echo $abc
[lu@bogon ~]$ abc={$xiaogan}nihao
[lu@bogon ~]$ echo $abc
{123}nihao
[lu@bogon ~]$
read 命令,对变量复制,通过文件或标准输入
[lu@bogon ~]$ read xg xiapgan
123 456
[lu@bogon ~]$ echo $xg
123
[lu@bogon ~]$ echo $xiaogan
123
[lu@bogon ~]$
[lu@bogon ~]$ read -p "input your password:" password
input your password:123456
[lu@bogon ~]$ echo $password
123456
[lu@bogon ~]$ read -s -p "input your password: " passwd #-s选项不回显
input your password: [lu@bogon ~]$ echo $passwd
123456
变量的作用域:
一般我们定义的变量都是只在当前的shell中可以使用,当到另一个shell中,就不能用了
[lu@bogon ~]$ echo $xg
123
[lu@bogon ~]$ bash
[lu@bogon ~]$ echo $xg
我们可以用export命令,将这些变量声明为全局变量,这样在新的shell中仍然可以使用:
explort xiaogan xg
[lu@bogon ~]$ exit
exit
[lu@bogon ~]$ echo $xg $xiaogan
123 123
[lu@bogon ~]$ export xg xiaogan
[lu@bogon ~]$ bash
[lu@bogon ~]$ echo $xg $xiaogan
123 123
[lu@bogon ~]$
set 用来显示本地变量
env 用来显示环境变量
export 用来显示和设置环境变量
区别:
set 显示当前shell的变量,包括当前用户的变量
env 显示当前用户的变量
export 显示当前导出成用户变量的shell变量
数值变量的运算
shell脚本的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等)
在shell环境中,只能进行比较简单的整数运算
运算符与变量之间必须有一个空格位
证书的运算主要是通过内部命令expr命令进行运算
Usage:变量1 运算符 变量2
其中变量1,变量2 对应的需要计算的数值变量(需要$符号调用)常用的集中运算符如下所示:
加法运算:+
减法运算:-
乘法运算:\* #由于*还有一个意思,所以需要使用反斜杠转义
除法运算:/
求模(取余)运算:%
[lu@bogon ~]$ a=5
[lu@bogon ~]$ b=10
[lu@bogon ~]$ expr $a + $b
15
[lu@bogon ~]$ expr $a \* $b
50
[lu@bogon ~]$ expr $b / $a
2
[lu@bogon ~]$ expr $b % $a
0
环境变量:
环境变量是指系统本身运行需要,由linux系统提前创建好的一类变量。
主要用于用户的工作环境,包括(用户的宿主目录HOME,命令的查找路径PATH,用户的当前目录PWD,登陆的终端SHELL等)环境变量的值由操作系统本身自己维护,随着用户的状态改变而改变
env调取当前环境变量
[lu@bogon ~]$ env
GS_LIB=
KDE_FULL_SESSION=true
XDG_MENU_PREFIX=kf5-
LANG=zh_CN.UTF-8
GDM_LANG=zh_CN.UTF-8
HISTCONTROL=ignoredups
PROFILEHOME=/home/lu
DISPLAY=:0
HOSTNAME=bogon
环境变量的配置文件在/etc/profile(全局)
1 # /etc/profile
2
3 # System wide environment and startup programs, for login setup
4 # Functions and aliases go in /etc/bashrc
53 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTR
PWD #pwd命令就是调用了这个变量才能进行输出
[lu@bogon ~]$ PWD=/etc
[lu@bogon etc]$ pwd
/home/lu
PATH
定义命令的默认搜索路径
我们讲的mysql可执行程序优化的时候我们是直接将程序路径写到了这个变量中才可以再任何目录下进行输入.
[lu@bogon etc]$ echo $PATH
/home/lu/.local/bin:/home/lu/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:.
USER
SHELL
HOME
[lu@bogon etc]$ echo $USER
lu
[lu@bogon etc]$ echo $SHELL
/bin/bash
[lu@bogon etc]$ echo $HOME
/home/lu
将我们所写的脚本放到$PATH的默认搜索路径中去
1.将/root目录写入到PATH的环境变量中,但是还没有永久生效
2.刷新一下/etc/profile 配置文件就可以永久生效了
3.之后/root下的可执行程序可以在任何目录下直接执行执行不许要任何命令去执行
[lu@bogon etc]$ echo $PATH
/home/lu/.local/bin:/home/lu/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:.
[lu@bogon etc]$ PATH=$PATH:/root
[lu@bogon etc]$ echo $PATH
/home/lu/.local/bin:/home/lu/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:.:/root
注:为了方便运行当前目录的可执行文件,所以我把 .(当前目录) ---> 也添加到了PATH变量中
位置变量
当执行命令行操作时第一个字段表示命令名或程序名
其余的字符串参数按照从左到右的顺序一次给位置变量赋值
位置变量也称为位置参数,使用$1,$2,$3....$9表示
例如:ls -a /root
其中ls表示命令字 -a 就是位置参数$1 /root就是位置参数 $2
vim sum.sh
#!/bin/bash
#sum
sum=$( expr $1 + $2 )
echp "$1 + $2 = $sum"
[lu@bogon etc]$ bash -x sum.sh 110 112
++ expr 110 + 112
+ sum=222
+ echo '110 + 112 = 222'
110 + 112 = 222
预定义变量:
$#:命令行中位置变量的个数(程序执行了几个位置参数)
$*:所有位置变量的内容(具体的内容 比如/root就是一个具体的内容)
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
判断是否出现错误正常为0异常错误为非0 取值在1-127之间
$0:当前执行的进程/程序名(就是当前执行的命令或程序的名字)
!$:上一条命令的最后一个参数
#!/bin/bash
file=back-$(date +%F).tar.gz
tar cvzf $file $* &> /root/tar.log
echo "the $0 scripts is running"
echo "total number of backup files is $#"
echo "the backup files is $*"
[root@bogon lu]# bash backup.sh /root /boot
the backup.sh scripts is running
total number of backup files is 2
the backup files is /root /boot
单引号:
要赋值的内容包括“$”,“\“等,
具有其他含义的特殊字符时,应使用单引号将其括起来;
在单引号范围内将无法引用其他的值,任何字符郡作为普通字符看待。
但赋值的内容包含单引号时需要使用‘\’符号进行转义以免冲突
[lu@bogon ~]$ welcome='$'xiaogan
[lu@bogon ~]$ echo $welcome
$xiaogan
[lu@bogon ~]$ welcome=\'xiaogan\'
[lu@bogon ~]$ echo $welcome
'xiaogan'
双引号:
1,当=号右边赋值出现空格的时候,需要使用双引号将其括起
2,在双引号的范围内还可以引用其他的变量,从而能够将现有的变量赋值给新的变量
[lu@bogon ~]$ welcome=hello world!
bash: world!: 未找到命令...
[lu@bogon ~]$ welcome="hello world!"
[lu@bogon ~]$ echo $welcome
hello world!
[lu@bogon ~]$ echo $xiaogan
123
[lu@bogon ~]$ welcome="hello world! $xiapgan"
[lu@bogon ~]$ echo $welcome
hello world!
反撇号:取值,同$()
[lu@bogon ~]$ which pwd
/usr/bin/pwd
[lu@bogon ~]$ rpm -qf `which pwd`
coreutils-8.30-6.fc29.x86_64
[lu@bogon ~]$ rpm -qf $(which pwd)
coreutils-8.30-6.fc29.x86_64
[lu@bogon ~]$ rpm -qf /usr/bin/pwd
coreutils-8.30-6.fc29.x86_64
反括号括起来的范围内必须是可执行的命令,否则将会出现错误
当发生嵌套时,反括号就不太好使了,这时我们会选择使用$()取值符号
[lu@bogon ~]$ rpm -q `rpm -qf `which pwd``
rpm:未给出要查询的参数
which-2.21-11.fc29.x86_64
未安装软件包 pwd
[lu@bogon ~]$ rpm -q `rpm -qf $(which pwd)`
coreutils-8.30-6.fc29.x86_64
[lu@bogon ~]$ rpm -q $(rpm -qf $(which pwd))
coreutils-8.30-6.fc29.x86_64
条件表达式
1,使用test命令进行判断
2,使用[ ]命令
Usage:test 条件表达式
Usage:[ 条件表达式 ]
1,文件测试
文件测试时指根据给定的路径名称,判断是文件还是目录,判断是具有读写执行的权限,判断文件目录是否存在
常用的选项如下:
-d :测试是否为目录(Directory)或目录是否存在
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)或文件是否存在
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
举例:一般我们挂载光盘的时候习惯将光盘挂载在/media/cdrom这个目录,但是rhel系统默认不存在这个目录,这时我们可以先判断一下这个目录是否存在
[lu@bogon ~]$ [ -d /media/cdrom ]
[lu@bogon ~]$ echo $?
1
[lu@bogon ~]$ test -d /media/cdrom
[lu@bogon ~]$ echo $?
1
我们使用[ ]的这种方式进行判断,这种也是最常用的一种格式注意两边最少需要一个空格位
使用echo输出一下$?可以看见返回值为非0通过判断的返回结果我们可以断定cdrom这个目录时不存在的
[root@bogon ~]# mkdir /media/cdrom
[root@bogon ~]# [ -d /media/cdrom ]
[root@bogon ~]# echo $?
0
当我们将cdrom这个目录创建完成之后在进行判断就是条件成立返回值为0这个表达式是成立的
通过查看变量$?的方式比较不直观我们可以用逻辑测试中的&来进行判断
[root@bogon ~]# [ -d /media/cdrom ] && echo “YES”
“YES”
[root@bogon ~]# [ -d /media/cdrom ] && echo “YES”
[root@bogon ~]#
在表达式的后面执行双&
如果前面的表达式成立则输出YES否则什么都不输出