什么是 Shell
# 查询 Shell 版本
echo $SHELL
# 返回:/bin/bash
# 查看支持哪些 Shell
cat /etc/shells
# CentOS 返回
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
什么是 Shell 脚本(Shell Script)
# echo 输出字符
# 通常在 Shell 脚本中使用 echo 输出字符值
# 既可以用它显示返回值,也可以使用 echo 输出脚本中运行中的变量值
# 从而来监控脚本的运行和调试
echo hello
echo "hello world"
# man 查看命令自带的手册
man echo
# **目录操作**相关命令
# ls 列出目录中所有的文件和目录,默认返回当前目录下所有的文件和目录
ls
ls / # 指定访问更目录
ls -a # 返回所有目录文件,包含隐藏目录和隐藏文件
ls -l
# 指定以长列表的形式来返回目录和文件的列表
#(能返回读写权限,所属的用户和用户组,文件大小以及文件时间)
ls -F # 列出的目录后加斜线标识
ll # ls 的别名
# cd 切换文件夹显示
cd / # 切换到更目录
cd .. # 返回上一级目录
cd ~ # 返回用户当前目录
# mkdir 常见一个新目录
mkdir test1 # 创建 test1 文件夹
rm test1.txt # 删除一个文件
rm -d test1 # 删除一个空目录
rm -rd test1 # 递归删除这个目录中所有内容
rm -rd test1 -v # 查看删除过程
# pwd 查看当前目录的绝对路径
# 在 Shell 脚本里经常使用 pwd 命令获取当前目录
# **文件操作**基本命令
# touch 创建一个文件
touch tf1
# cat / more / less / tail / head 查看文件
echo hello world > tf1 # 向文件 tf1 中写入 hello world
cat tf1 # 查看文件所有内容(对大件显示不友好)
more /etc/passwd
# 在一屏中显示,同时最下方标识出显示的进度,空格进行翻页
less /etc/passwd
# cp 复制文件
cp tf1 ../test2/ # 将 tf1 文件拷贝到 test2 目录中
# mv 重命名或者移动文件
mv tf1 tf2 # 将文件 tf1 重命名为 tf2
mv tf2 ../test2/ # 将文件 tf2 移动到 test2 目录
# rm 删除文件
rm ../test2/tf1 # 删除的文件找不回来,所以使用要非常慎重
# 编辑器
# vim 在命令行界面中进行编写
vim vt1 # 编辑 vt1 文件,如果文件不存在会自动创建
# 输入一个“:”,会等待接受一个命令
# 输入“q”,就是退出命令,
# 对于一个新建的文件,输入“q”,并没有保存,退出后就不会有 vt1 这个文件
# 输入“w”,文件就会被写入,这时候再输入“q”命令退出, tf1 这个文件就会存在
# 输入“i”,可以插入字符
# 点击“Esc”键,就可以退出插入模式
# 如果修改了文件不想保存,就可以使用“!”强制操作。输入“:q!”放弃修改强制退出
# 如果修改了想保存,输入“:wq”,保存修改退出
# 创建一个存放 Shell 脚本文件的文件夹 shellscript
cd /data/
mkdir shellscript
# 进入 shellscript 文件夹,新建 Shell 脚本文件
cd shellscript
touch helloworld
# 使用 vim 编辑器打开文件
vim helloworld
# 切换到 insert 模式,开始编辑
## 文件开始 ##
# 脚本开头,要使用“#!” 加指定的bash:/bin/bash 标识这个文件,
# 这样就将文件编程了bash的脚本文件
#!/bin/bash
# 输出一个字符串
echo helloworld
## 文件结束 ##
# 保存退出后
helloworld
# 返回:bash: helloworld: 未找到命令。
# 因为系统会根据环境变量中配置的 PATH 来查找命令的目录
# 我们并没有配置环境变量,所以要指定要执行的文件
# 执行当前目录中的 helloworld 文件
./helloworld
# 返回:bash: ./helloworld: 权限不够
# 添加执行权限
chmod u+x helloworld
# 再执行 helloworld,输出:helloworld
vim add
# 切换到 insert 模式,开始编辑
## 文件开始 ##
#! /bin/bash
# 输出提示语
echo "Please type first number:"
# 使用 read 读取变量
read param1
echo "Please type second number:"
read param2
# 做加法操作
# 引用变量前,要在变量前添加“$”符号
result=$[$param1+$param2]
echo "The result is:"$result
## 文件结束 ##
# 保存退出后
# 添加执行权限
chmod u+x add
# 执行
./add
Please type first number:
1
Please type second number:
2
The result is:3
Var=2
。注意声明变量的时候,等号左右不要有空格。$Var
var=12
echo $var # 输出 12
var=hello # 修改变量
echo $var # 修改了变量值,输出 hello
var='hello world' # 赋值一个有空格的字符串,要用单引号
var2='hello $var world' # 使用**单引号**会完整的将单引号中的部分传递给赋值的变量
echo $var2 # 输出 hello $var world
var2="hello $var world"
# 给变量赋其它字符串的值,要使用**双引号**,
# 会将双引号中使用的变量值解析后再赋给我们需要的变量
echo $var2 # 输出 hello hello world world
# 日期类型
date # 返回 2019年 07月 22日 星期一 22:17:03 CST
var=date
echo $var # 输出 date。系统默认把 date 当字符串赋给变量。
var=`date`
# 使用反引号“`”。作用是能够将反引号中包含的 Shell 命令执行后将结果赋给变量
echo $var # 输出 2019年 07月 22日 星期一 22:19:39 CST
var=`date +%Y%m%d` # 反引号中实现 date 的格式化
echo $var # 输出 20190722
env
和 set
命令访问到环境变量env # 查看所有环境变量
env | less # 用管道的组合命令将值传给文件查看命令
echo $PATH # 访问单个环境变量
set
# 返回的环境变量更加多,它也可以返回当前 Shell 进程中已经定义的变量
# 修改环境变量
PATH=$PATH:/data/shellscript
#创建新环境变量
PATH_SELF=`pwd`
echo $PATH_SELF # 输出 /data/shellscript
# 新建一个脚本文件
vim envpath
# 写入
#! /bin/bash
echo $PATH_SELF
# 保存退出,修改文件权限
chmod u+x envpath
# 执行脚本
./envpath
# 输出为空,脚本不能访问到刚才定义的值,这个值不能被全局访问
# 把局部变量导出为全局变量
export PATH_SELF
# 再执行脚本
./envpath # 输出 /data/shellscript
export
设置环境变量会随着 Shell 进程的结束而失效/etc/profile
加载 /etc/bashrc
和 /etc/profile.d
目录$HOME/.bash_profile
、$HOME/.bashrc
/etc/
下的配置所有用户都可以用,$HOME
下的配置,仅体现在特定的用户中# 设置环境变量永久化
# 修改 /etc/profile
vim /etc/profile
## shift + G 移动到文件最底部,在 export 命令行上一行(如果有)输入
PATH=$PATH:/data/shellscript
# 保存退出,使文件立即生效
source /etc/profile # source 命令还有一个别名:.
# 系统 /etc/profile 的文件会在每次系统启动时调用,所有修改了需要 source 命令刷新
# 用户目录下的 $HOME/.bashrc 配置文件会在每次新开进程时都会调用,相当于在子进程中调用多次
vim $HOME/.bashrc
# 以下命令,为别名的设置,也是一种变相的全局变量
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
str=hello
str1=world
str=$str$str1 # 连接字符串不需要任何操作符,只需要紧挨着写
echo $str # 输出 helloworld
str=$str' '"12345"
echo $str # 输出 helloworld 12345
str=$str:
echo $str # 输出 helloworld 12345:
str="Test: $str"
echo $str # 输出 Test: helloworld 12345:
expr length $str
expr length "hello" # 输出 5
expr length "$str" # 输出 23(Test: helloworld 12345:)
charcount=`expr length "$str"` # 将 expr 的结果保存在变量中
echo charcount # 输出 23
expr index $str CHARS
expr index "$str" 'h' # 输出 7(返回第一个匹配的位置的索引值,1 起始)
expr substr $str POS LENGTH
expr substr "$str" 7 10 # 输出 helloworld
expr $str : REGEXP
(连续的字符串会被认为是字符串之间的连接,所以在进行字符串匹配时,前面的原字符串和后面的正则表达式这两个串,中间使用的冒号前后都要添加空格)expr match $str REGEXP
(和上面的几乎没区别,使用 match 在程序的阅读上会带来更大的便利)expr "$str" : '.*' # 匹配所有的任意字符串,输出 30
# 匹配数字,先写正则: .*[0-9]{5}
# 要返回特定的子字符串:.*([0-9]{5})
# 要为使用的特殊符号转义:.*\([0-9]\{5\}\)
expr "$str" : '.*\([0-9]\{5\}\)' # 输出 12345
# 匹配字母以及冒号,先写正则: [a-zA-Z: ]*.*
# 要返回特定的子字符串:([a-zA-Z: ]*).*
# 要为使用的特殊符号转义:\([a-zA-Z: ]*\).*
expr "$str" : '\([a-zA-Z: ]*\).*' # 输出 Test: helloworld
&
、|
、<
、>
、=
、!=
、<=
、>=
+
、-
、*
、/
、%
、()
expr expression
result=$[expreesion]
,这种方式更加简便num1=7
num2=13
num3=7
# “<”在 Shell 脚本中有另外的含义,在输入输出流中会使用到的一个符号
# 所以用了 expr 命令 就要使用转义符号
expr $num1 \< $num2 # 所有的逻辑判断返回值都是 0 或者 1。输出 1
expr $num1 \< 19 # 输出 1
result=$[$num1 < 19]
# 使用“[]”,就可以不使用转义符。小于号左右的空格也可以去掉,加了空格,表达式更加的可读
echo $result # 输出 1
expr $num1 = $num3
# 使用 expr,等号左右**必须**添加空格,否则就是字符串连接输出操作。输出 1
result=$[$num1 == $num3] # 使用“[]”在等于比较时,要使用双等于号“==”
echo $result # 输出 1
expr $num1 \* $num2 # 输出 91
result=$[$num1 * $num2] # Shell 脚本编程中 通常使用这种方式
echo $result # 输出 91
result=$[$num1 / $num2]
echo $result # 输出 0(Shell 脚本默认只能进行整形操作)
bc
yum -y install bc # 安装 bc
bc # 启动 bc
12.5*3 # 输出 37.5
100/3 # 输出 33()
scale=4 # 默认 scale=0,可设置 scale 数值大于 0 得到浮点值
100/3 # 输出 33.3333
3.156*(3+5) # 输出 25.248
quit # 退出 bc
bc -q # 再次启动 bc(没有软件版本信息)
3.44/5 # 输出 0(重启 bc 的话 scale 设置失效)
scale=4
3.44/5 # 输出 .6880
num=12 # 声明变量
num2=3;num3=17 # 声明多个变量,分号分割
num3/num # 输出 1.4166
# 使用管道命令:可以将需要计算的表达式和选项通过 echo 语句输出、
# 并且通过管道输出给计算器,将返回值存储在变量中
# 格式:
var =`echo "options; expression" | bc`
# 管道命令是在 Shell 中比较常见的用来进行程序之间数据输出的一个命令
# 它将前一个命令的输出作为后一个命令的输入传输进去
# 举例:
var=`echo "scale=4;3.44/5" | bc`
echo $var # 输出 .6880
# 以管道的形式来调用 bc 计算器,很难在其中写一些比较复杂的计算式,
# 比如需要一些中间变量的计算。
# 所以可以使用以下的方式来调用 bc 计算器
# 这是一个内连的输入重定向
# EOF 允许在控制台重新定向数据
# 格式:
var = `bc<<EOF
options
statements
expressions
EOF
`
# 举例:
var1=10.46
var2=43.67
var3=33.2
var4=71
result=`bc << EOF
scale=4
a1 = $var1 + $var2
b1 = $var3 * $var4
a1+b1
EOF
、
echo $result # 输出 2411.33