shell简介
- 什么是shell?
把在终端下可执行的命令保存到文件中,这个文件就是shell程序。 - shell的类型?
ash、bash、ksh、csh等,
查看默认shell使用echo $SHELL
/etc/shells文件中存放了当前系统中可用的shell - shell脚本的执行
- 使用指定shell执行指定脚本:
bash hello.sh
,该文件可以没有可执行权限 - 将shell脚本文件作为可执行程序执行,必须添加可执行权限
- 添加可执行权限:
chmod +x hello.sh
- 在开头指定
shell:#!/bin/bash
,其他位置#表示注释 - 执行脚本:
- 在本目录:
./hello.sh
- 不再本目录:
/home/jerry/shell/hello.sh
- 在本目录:
- 添加可执行权限:
- 使用指定shell执行指定脚本:
shell变量
-
定义变量:
name="xiaoming"
-
打印变量:
echo $name 或 echo ${name}
-
销毁变量:
unset name
-
声明常量:
readonly name="xiaoming"
- 注意事项:使用’='时,两边不能有空格
变量类型
- 本地变量: 只适用于当前shell的变量
- 环境变量: 适用于整个系统,通常都是全大写的
- 查看环境变量:
env
- 打印指定变量:
echo $PATH
- PATH:若想让你的脚本哪里都可以使用,需要将脚本路径添加到PATH环境变量中
- 修改:
- 一次性:
export PATH=$PATH:/home/jerry/shell
- 永久性:
- 系统:
/etc/profile
- 用户:
~/.profile、~/.bashrc、~/.bash_profile
- 重新加载(立即生效):
source filename
或. filename
- 系统:
- 一次性:
- 查看环境变量:
- 位置变量
- $0:表示脚本名
- $1 ~ $9:表示传递给脚本的参数
- 特殊变量
- $#:传递给脚本参数的个数
- $*:传递给脚本的所有参数
- $?:上次命令执行情况,0表示正确,其他表示错误
单双引号的区别
- 双引号: 可以是除$、`、\、"之外的任意字符
- 单引号: 其中的任意字符都不解析,都会原样输出
- 反引号: 会将其中的内容作为命令执行
- 反斜线: 转义特定的字符,如:&、*、?、|、^、$、`
字符串操作
- 计算长度:
${#name}
- 提取字符:
${name:2:3}
从下表为2的字符开始提取,提取3个字符
数组操作
- 定义:
a=(1 2 3)
- 成员:
${a[0]}
- 长度:
${#a[@]}
- 所有元素:
${a[*]}
,使用for-in遍历时需要提取元素
seq
- 说明:生成连续的整数
- 示例:seq 1 10,生成1-10的连续整数
expr
- 说明:运算一个表达式
- 示例:
expr 1 + 2 # 结果为3
echoexpr 1 + 2
# 结构为3
expr 3 * 5 # *需要转义
各种运算
-
test命令,成功为真,失败为假;测试结果通过$?检查,0代表真,1代表假。
#!/bin/bash if test 1 -lt 2; then echo "OK" fi # []中,前后都需要空格 if [ 1 -lt 2 ]; then echo "ok" fi
-
数值比较
- -lt:小于
- -le:小于等于
- -gt:大于
- -ge:大于等于
- -eq:相等
- -ne:不相等
-
字符串测试
- =:相等
- !=:不相等
- -z:字符串长度是否为0
- -n:字符串长度是否不为0
-
文件判断
- -f:普通文件
- -d:目录文件
- -c:字符设备文件
- -b:块设备文件
- -w:文件存在,且可写
- -x:文件存在,且可执行
- -s:文件存在,且至少有一个字符
-
逻辑运算
-
-a:逻辑与(and),也可以使用 && 进行转换
-
-o:逻辑或(or),可以使用||进行转换
-
!:逻辑非
-
示例:
if [ 1 -lt 3 -a 2 -lt 3 ]; then
echo “ok”
fiif [ 1 -lt 3 ] && [ 2 -lt 3 ]; then
echo “ok”
fiif [ ! 1 -gt 3 ]; then
echo “ok”
fi
-
分支结构
-
if-else
if [ 1 -lt 3 -a 2 -lt 3 ]; then echo "ok" fi if [ 1 -lt 3 ] && [ 2 -lt 3 ]; then echo "ok" fi if [ ! 1 -gt 3 ]; then echo "ok" fi
-
case
从终端获取内容,-p后的字符串为提示字符read -p 'press any key:' ch
case $ch in [a-z]) echo 'alpha' ;; [0-9]) echo 'numberic' ;; *) echo 'other' ;; esac
循环结构
-
for-in及for
for x in a b c do echo $x done
for x in /etc/* do echo $x done
for x in seq 1 10 do echo $x done
for i in seq 1 100 do let j+=$i done
echo $j a=(1 2 3) for x in ${a[*]} do echo $x done
for ((i=0;i<=${#a[@]};i++)) do echo ${a[$i]} done
-
while
i=1 sum=0 while [ $i -le 10 ] do ((sum+=$i)) let sum+=$i sum=$[$sum+$i] ((i++)) let i++ let i+=1 i=$[$i+1] done echo $sum
-
until
i=1 until [ $i -gt 10 ] do echo $i ((i++)) done
break、continue:自行学习
函数
demo()
{
echo 'call demo func'
}
demo
arg()
{
echo $1
echo $2
echo $#
echo $*
return 123
}
arg 1 2
# $? 表示函数的返回值
echo $?
服务管理
- 管理操作:
- 格式:service 服务 操作
- 示例:
service ssh start|stop|restart
- 配置服务
- 在/etc/init.d/目录下创建一个脚本文件(test),添加内容如下:
#!/bin/bash
echo “for test” - 给脚本文件添加可执行权限:
sudo chmod +x test
- 服务测试:
service test
- 若这样测试:
service test start
则会出现服务找不到错误sudo update-rc.d test defaults
能够解决服务不存在的问题- 其实是将/etc/init.d/test脚本在不同的运行模式启动脚本目录创建软链接
- 再次测试不出现打印结果,那是因为所有使用service其他的服务都是后台运行
sudo systemctl status test
即可查看服务状态
- 当服务脚本更新是需要使用
sudo systemctl daemon-reload
进行重新加载 - 移除服务:
sudo update-rc.d -f test remove
- 说明:每个启动模式下的脚本,K开头表示停止,S开头表示启动,后面数字代表执行顺序
- 在/etc/init.d/目录下创建一个脚本文件(test),添加内容如下: