文章目录
shell概述
shell:一个可以在linux(Unix)中执行的脚本,内部包含了linux的命令的集合
#!/bin/bash
ls
cd ..
ls -lh
命令:修改文件权限
r read 读 w write 写 x execute 执行
文件用户组: 所属用户(u user) 所属组(g group) 其他用户(o other) 所有用户(a all)
chmod 文件用户组 +|- 权限 文件名
chmod a+x 01test
shell运行方式
在子进程中运行:
chmod 文件用户组 +|- 权限 文件名.sh
./文件名.sh
/bin/bash ./文件名.sh
在主进程中运行
source ./文件名.sh
. ./文件名.sh
变量定义和使用
变量名=值
等号前后不能有空格 变量名遵循标识符命名规则
打印变量
echo $ 变量名
变量的分类
环境变量
export 变量名=值
本地变量
local 变量名=值
local修饰的变量只能出现在函数中
删除变量
unset 变量名
删除后的变量没有值 打印不会出错
通配符
* 表示匹配任意0到多个字符
? 表示匹配任意一个字符
[区间][a-d] [权值][abcd] 表示配匹[]内的一个字符
#!/bin/bash
#* 表示匹配任意0到多个字符
#匹配.sh为结尾前面是任意字符的文件名
ls *.sh
#? 表示匹配任意一个字符
ls ???????.sh
#[区间][a-d] [权值][abcd]
ls [0-9][01]*.sh
命令代换
`命令` 由“`”反引号括起来的也是一条命令,Shell先执行该命令,然后将输出结果立刻代换到当前命令行中。
value=`ls`
echo $value
算数代换
使用运算符进行计算
- $((表达式))
- $[表达式]
# 算数运算符计算
i=123
echo $(($i+321))
echo $[$i+321]
进制的计算
$[进制#值]
# 进制的计算
echo $[8#20+16#20]
echo $[16#20+20]
转义字符
\ 在linux有一些特殊字符被占用 可以使用\ 转义字符 表示原始意思
#!/bin/bash
cd ..
ls 0*
ls 0\*
echo \\
#创建新文件$ $
touch \$\ \$
引号使用
’ ’ 将单引号内部内容正常打印
#!/bin/bash
i=123
value='$i+345
hello world
你好'
echo $value
“” 将引号内容转义字符正常打印 变量或表达式 计算结结果打印
#!/bin/bash
#data=$[i+345]
data="\\\$\ \n"
echo "$data"
脚本语法
条件测试
test 表达式 判断表达式的内容 如果为真 返回值为0 如果为假 返回值为非0
[ 表达式 ] 判断表达式的内容 如果为真 返回值为0 如果为假 返回值为非0
如果想打印test对应的结果内容 使用$?
-eq 相当于运算符 ==
-ne 相当于运算符 !=
-gt 相当于运算符 >
-lt 相当于运算符 <
-ge 相当于运算符 >=
-le 相当于运算符 <=
#!/bin/bash
value=123
test $value -gt 110
echo $?
test $value -eq 100
echo $?
[ $value -le 100 ]
echo $?
分支选择
if
if 表达式
then
脚本1
else
脚本2
fi
如果表达式为真 执行脚本1内容 如果为假执行else中脚本2
fi 表示if语句的结束
if 表达式1
then
脚本1
elif 表达式2
then
脚本2
else
脚本3
fi
#!/bin/bash
#if [ -f 01_test.sh ]
#then
# echo "这是一个文件"
#else
# echo "这不是一个文件"
#fi
#score=0
echo "请输入考试成绩"
#通过键盘获取数据时 不需要添加 $
read score
if [ $score -ge 700 ]
then
echo "我要上清华"
elif [ $score -ge 680 ]
then
echo "我要上北大"
else
echo "我要上传智"
fi
case
case 表达式 in
值1)
脚本1
;;
值2)
脚本2
;;
*)
脚本3
;;
* 表示默认匹配 相当于default
;; 表示一个分支的结束 相当于break
#!/bin/bash
echo "请输入yes或no"
read value
case $value in
#yes|y|YES|Yes)
[Yy][Ee][Ss])
echo "早上好"
;;
no|No|NO|n)
echo "下午好"
;;
*)
echo "输入错误"
;;
esac
循环语句
for
for 变量 in 集合
do
脚本
done
#!/bin/bash
#for fruit in apple banana pear;
#do
# echo "I like $fruit"
#done
#计算1-100和
sum=0
for i in {1..100};
do
sum=$[$sum+$i]
done
echo $sum
while
while 表达式
do
脚本
done
#!/bin/bash
#echo "请输入密码"
#read passwd
#while [ $passwd != "123456" ];
#do
# echo "密码错误 请重新输入"
# read passwd
#done
#echo "密码正确"
i=0
while [ $i -lt 10 ];
do
echo $i
i=$[$i+1]
done
跳出语句
break[n]可以指定跳出几层循环
continue跳过本次循环,但不会跳出循环。
#!/bin/bash
i=0
echo "请输入密码"
read passwd
while [ $passwd != "123456" ];
do
echo "密码错误 请重新输入"
i=$[$i+1]
if [ $i -eq 5 ]
then
echo "密码错误,系统锁定"
break
fi
read passwd
done
位置参数和特殊变量
$0 相当于C语言main函数的argv[0]
$1、$2… 这些称为位置参数(Positional Parameter),相当于C语言main函数的argv[1]、argv[2]…
$# 相当于C语言main函数的argc - 1,注意这里的#后面不表示注释
$@ 表示参数列表"$1" “$2” …,例如可以用在for循环中的in后面。
$* 表示参数列表"$1" “$2” …,同上
$? 上一条命令的Exit Status
$$ 当前进程号
#!/bin/bash
echo $0
#echo $1
#echo $2
#echo $3
for i in $*
do
echo $i
done
echo $$
输入输出
输出
echo 选项 字符串
-n 表示输出不换行 默认echo输出自带换行
-e 表示在输出时解析转义字符
#!/bin/bash
#echo -n "你好"
#echo -n "世界"
#echo -e "hello\n\n"
read score str
echo $score
echo $str
管道
管道:将一个命令的输出作为另外一个命令的输入
命令 | 命令
tee
tee命令把结果输出到标准输出,另一个副本输出到相应文件。
命令 | tee 文件
#!/bin/bash
cat error.log | grep "404" | tee a.log
cat error.log | grep "502" | tee b.log
cat error.log | grep "error" | tee c.log
函数
在shell中函数必须先定义后使用
#定义函数
函数名
{
脚本
}
#调用函数
函数名 参数
#!/bin/bash
value=0
function demo
{
# echo "这是一个函数"
for i in $@
do
echo $i
done
return 0
}
#定义函数 并为函数传递参数
if demo 123 456 888
then
echo "if条件成立"
else
echo "if条件不成立"
fi
遍历文件
#!/bin/bash
cd ../../
value=`ls`
function foreach
{
for i in $@
do
if [ -d $i ]
then
echo "$i 这是一个目录"
else
echo "$i 这不是一个目录"
fi
done
}
#`foreach "/home/anolgame" "../" "error.log"
foreach $value
脚本调试方法
解析器 -n 文件.sh 检测语法 不允许程序 将错误信息输出
解析器 -v 文件.sh 一面执行脚本 一面打印信息
在代码中设置调试的标志位
set -x 设置标志位
脚本
set +x 取消标志位
正则表达式
[] 匹配中括号中的一个字符 [区间][权值]
{n} 表示选择的数据为n个
{n,m} 选择数据最少是n个 最多是m个
{n,} 最少是n个数据
{,m} 最多是m个数据
+ 前面数据内容匹配一个或多个
* 前面数据内容匹配0个或多个
? 前面数据内容匹配0个或者一个
. 表示匹配任意一个内容
\ 转义字符 表示使用字符本意
^test 表示匹配以test开头的内容
[^] 匹配括号外的字符
test$ 匹配一test为结尾的内容
\<test 以test为开头的单词
test\> 以test为结尾的单词
\btest 以test为开头
test\b 以test为结尾
\btest|test\b 以test开头以test为结尾
| 表示以或的方式连接两个表达式
() 表示一个集合 可以对集合进行统一操作
cat file | egrep [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
cat file | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
cat file | egrep '[a-z]{1,3}\.[a-z]{1,3}\.[a-z]{1,3}\.[a-z]{1,3}'
cat file | egrep '[a-zA-Z_]+[a-zA-Z0-9_]*'
cat file | egrep 'a..'
cat file | egrep '[a-zA-Z0-9_]+@[a-zA-Z0-9]+[a-zA-Z0-9_]*\.[a-zA-Z]+'
#匹配1开头的内容
cat file | egrep '^1'
#匹配配t开头的内容
cat file | egrep '^t'
#匹配英文字母开头的内容
cat file | egrep '^[a-zA-Z]'
#匹配非数字开头的内容
cat file | egrep '^[^0-9]'
#匹配数字结尾的内容
cat file | egrep '[0-9]$'
#匹配英文字母结尾的内容
cat file | egrep '[a-zA-Z]$'
#匹配非数字8结尾的内容
cat file | egrep '[^8]$'
#匹配te开头的单词
egrep '\<te' file
#匹配23结尾的单词
egrep '23\>' file
#匹配以t开头的单词
egrep '\bt' file
#匹配以t结尾的单词
egrep 't\b' file
#匹配以t开头或以t结尾的单词
egrep '\bt|t\b' file
#将()内的内容理解为一个集合 对集合进行统一操作
cat file | egrep '([0-9]{1,3}\.){3}[0-9]{1,3}'
#匹配test 或者text 内容
cat file | egrep 't(est|ext)'
grep
文本搜索查找
egrep
fgrep
参数:
- -c 表示输出匹配的行个数
- -i 搜索时不区分大小写 abc ABC AbC
- -h 多文件查找是不显示文件名
- -l 多文件查找值匹配文件名
- -n 显示行号
- -v 反选 不包含搜索内容的数据
#显示file文件中包含abc的行数
grep -c 'abc' file
#搜索file文件中忽略大小写的abc
grep -i 'abc' file
#搜索file error.log 文件 中忽略大小写的abc
grep -i 'abc' file error.log
#多文件搜索时不显示文件名
grep -ih 'abc' file error.log
#多文件搜索时显示匹配的文件名
grep -l 'abc' file error.log
#显示搜索的行号
grep -n '23' file error.log
#反选显示不包含搜索内容
grep -v '23' file
#搜索连续5个小写字符
grep '[a-z]\{5\}' file
#搜索连续5个数字
grep '[0-9]\{5\}' file
find
查找文件
find 路径
-name 基于名字搜索
-type 基于类型搜素
d 目录 l 链接 c 字符设备 b 块设备 s 管道 f 普通文件
-perm 基于权限查找
777 每一个7 表示一组权限 r 4 w 2 x1
-perm 766 522 r-x -w- -w- 600 rw- — ---
第一个7表示所属用户
第二个7表示所属组
第一个7表示其他用户
-user 基于用户搜索
-group 基于组搜索
-mtime 基于时间搜索
-n 距离n天以内的搜索
+n 距离n天以外的搜索
sed (内容庞大,可单独总结)
流编辑器
sed 选项 脚本 文件1 文件2
脚本:
a 追加 sed ‘2a test’ 文件名 在第二行后追加test
p 打印 sed -n ‘/test/p’ 文件名 打印包含test的内容
d 删除 sed ‘nd’ 文件 名表示删除第n行内容 sed ‘n,md’ 文件名 删除从n开始到m行的内容
s 替换 sed ‘s/test/xxxx/g’ 文件名 将文件中的test使用xxxx替换
注意:并没有修改源文件内容