shell编程
管道及xargs
- |:将前面命令的输出作为后面命令的参数。如:
ls /bin | grep '^m'
- xargs:有些命令无法接受管道参数,可以通过xargs解决。如:
find -name 2.txt | xargs rm -rf
重定向
标准输入(stdin)、标准输出(stdout)、标准错误(stderr)
在linux中,创建任意进程,系统会自动创建上面三个数据流,其实就是三个文件
三个文件的描述符分别是:0、1、2,都指向了终端
重定向就是改变原来默认的表现位置。
演示:
1
2
3
4
5
6
7输出重定向:
ls > 1.txt # 会新建文件,若文件已存在,会清空
ls >> 1.txt # 追加到文件末尾,若文件不存在则创建
错误重定向:
ls /xxx 2> 1.txt # 将标准错误重定向到1.txt
同时重定向输出和错误:
ls /xxx /home &> 1.txt # 将标准输出和错误同时重定向到1.txt文件
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表示正确,其他表示错误
单双引号的区别
- 双引号:可以是除下面之外的任意字符
1 | 、`、\、" |
- 单引号:其中的任意字符都不解析,都会原样输出
- 反引号:会将其中的内容作为命令执行
- 反斜线:转义特定的字符,如:
1 |
字符串操作
- 计算长度:
1 | {#name} |
- 提取字符:
1 | {name:2:3} |
从下表为2的字符开始提取,提取3个字符
数组操作
- 定义:
a=(1 2 3)
- 成员:
1 | {a[0]} |
长度:
1
{#a[@]}
所有元素:
1
{a[*]}
使用for-in遍历时需要提取元素
seq
- 说明:生成连续的整数
- 示例:
seq 1 10
,生成1-10的连续整数
###expr
说明:运算一个表达式
示例:
1
2
3expr 1 + 2 # 结果为3
echo `expr 1 + 2` # 结构为3
expr 3 \* 5 # *需要转义
各种运算
test命令,成功为真,失败为假;测试结果通过$?检查,0代表真,1代表假。
1
2
3
4
5
6
7
8
9!/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)
,可以使用||进行转换!
:逻辑非- 示例:
1
2
3
4
5
6
7
8
9
10
11if [ 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
分支结构
if-else
1
2
3
4
5
6
7
8
9
10
11if [ 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"
ficase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16从终端获取内容,-p后的字符串为提示字符
read -p 'press any key:' ch
case $ch in
[a-z])
echo 'alpha'
;;
[0-9])
echo 'numberic'
;;
*)
echo 'other'
;;
esac
循环结构
for-in及for
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32for 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]}
donewhile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15i=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 $sumuntil
1
2
3
4
5
6
7i=1
until [ $i -gt 10 ]
do
echo $i
((i++))
donebreak、continue:自行学习
函数
1 | demo() |
服务管理
管理操作:
- 格式:
service
服务 操作 - 示例:
service ssh start|stop|restart
- 格式:
配置服务
在
/etc/init.d/
目录下创建一个脚本文件(test),添加内容如下:1
2!/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开头表示启动,后面数字代表执行顺序