自动部署系统需要重构一下脚本,就抓紧系统学习了一下shell脚本,本文是一些笔记整理
#tee命令接受来在cat a*的sudin(标准输入)的数据,将stdout(标准输出)的一份副本写入文件out.txt ,同时将另一份副本作为后续命令的stdin,命令cat -n将sudin中接受到的没一行数据前加上行号并写入stdout
$cat a* | tee out.txt | cat -n
#/dev/null是一个特殊的设备文件,这个文件会将接受到的所有数据都丢掉
cat error.txt >> /dev/null
向log文件写入头部数据
#! /bin/bash
cat <<EOF>> log.txt
LOG FILE HEADER
12344567
Function:System statistics
EOF
函数中可以使用
fname()
{
echo $1 $2
chod "$@" 打印 参数
}
for 循环
for var in list;
do
commands;#使用变量
done
list can be a string or a sequence
也可以
for((i=0;i<10;i++)){
commands;
}
while condition
do
commands ;
done
比较和测试
if condition;
then
commands;
fi
else if 和 else
if condition;
then
commands;
elif condition;
then
commands
else
commands
fi
-eq 相当
-ne 不等
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于
文件系统相关测试
[ -f $file_var ] 文件存在
[ -x $var] 可执行
[ -d $var] 是目录
[ -e ] 文件存在
[ -w] 可写
[-r] 可读
[-L ] 是个符号链接
字符串比较
1.字符串比较最好采用双引号
-z 查看是否是空字符串
-n 非空字符串
if [[ -n $str1 ] ] && [[ -z $str2 ]];
then
fi
也可以使用 test命令
if test $var -eq 0; then echo "true";fi
equal
if [ $var -eq 0 ]
0
文件查找与文件列表
find命令的工作方式如下:沿着文件层次结构向下遍历,批判符合条件的文件,并执行相应的操作
1.根据文件名或正则表达式匹配搜索
find /duplicatedcode/ -name "*.txt" -print
如果匹配多个
find /duplicatedcode/ \( -name "*.txt" -o -name "*.java" \) -print
用正则式匹配.py 或者 .sh文件
$ find . -regex ".*\(\.py\|\.sh\)$"
2.否定参数 "!" 就是不查找以 .txt结尾的
find /duplicatedcode/ ! -name "*.txt" -print
3.搜索深度
-maxdepth 和 -mindepth 应该作为find的第三个参数出现,如果作为第四个参数 可能会影响到find的效率
3.1 制定最大深度为1
find . -maxdepth 1 -type f -print
3.2 指定最小深度
find . -mindepth 1 -type f -print
根据文件时间进行搜索
1.访问时间 (-atime) 用户最近一次访问文件的时间
2.修改时间(-mtime) 文件内容最后一次被修改的时间
3.变化时间(-ctime) 文件元数据 (例如权限)最后一次改变的时间
1.打印最近7天内被访问过的所有文件
find . -type f -atime -7 print
2.打印7天前被访问过的所有文件
find . -type f -atime 7 -print
3.打印访问时间超过7天的时间
find . -type f -atime +7 -print
基于文件大小的搜索
查找大于1g的文件
find . -type f -size +1G
7.删除匹配的文件
find . -type f -name "*.swp" -delete
8.基于文件权限和所有权的匹配
find . -type f -perm 644 -print
例如查找执行权限为644的java文件
find . -type f -name "*.java" | -perm 644 -print
find跳过特定的目录
比如需要跳过.svn目录
find devel/source_path \( -name ".svn" -prune \) -o \( -type f -print \)
这里的 -name ".svn" -prune 的作用是排除
xargs :可以将标准输入转换为命令行参数
例如删除svn文件
find . -name ".svn" | xargs rm -rf 不要
find . -name ".svn" -print0 | xargs -0 rm -rf 推荐
第一种是没法预测分割find命令输出结果的定界符是"\n" 还是 " ",很多文件都包含空格,而xargs 会误认为他们是定界符
所以只要 结合使用 find ,就不行将 -print0 与find结合使用,已字符null来分隔输出.
分割文件 将分割file为10k大小
split -b 10k file
提取扩展名
${var%.*}
从 $var中删除位于%右侧的通配符所匹配的字符串,通配符从右向做左进行匹配
例如 var为a.b.jpg则会匹配 a.b
如果采用贪婪
${var%%.*} 则会匹配 a
相同还有
${var#*.} 执行从左到右匹配 输出 b.jpg
${var##*.} 输出jpg
//创建多级目录
mkdir -p /home/data/
更改所有权
chown user.group filename
递归设置权限
chmod 777 . -R
递归设置所有权
chown user.group . -R
设置粘滞位
chmod a+t directory_name
touch 更改时间戳
touch -a 只更改文件访问时间
touch -m 只更改文件内容的修改时间
符号链接 删除不影响
ln -s target symbolic_link_name
查找符号链接
find . -type l -print
统计行数
wc -l
cat file | wc -l
echo -n 1234 | wc -l
打印最上行的长度
wc file -L
正则表达式基本对照表
^ 行 开始位置
$ 行尾位置
. 匹配任意字符
[] 匹配包含在[字符]之中的任意一个字符
[^] 匹配除[^字符]之中的任意一个字符
[-] 匹配[]中制定范围内的任意一个字符 如果[1-5] 匹配 1-5的字符串
? 匹配之前的项1次或者0次 例如 duplicated?code 匹配 duplicatedcode 或者 duplicatecode 但不匹配 duplicateddcode
+ 匹配之前的项1次或多次
* 匹配之前的项0次或多次
() 创建一个用于匹配的字符串 例如 qnmlgb(and)x 匹配 qnmlqbx 或 qnmlgbandx
{n} 匹配之前的项n次 [0-9]{3} 批评任意一个三位数
{n,} 之前的项至少需要匹配n次 [0-9]{3.} 必须为三位数字或更大
{n,m} 指定的项最少次和最大次
| 交替,匹配 | 两边的任意项 abc (1|2) 匹配 abc1 abc2
\ 转义字符 例如 duplicatedcode\.com 则必须匹配 duplicatedcode.com
grep -E "[a-z]" 通过正在表达式查找
递归搜索文件
grep "duplicatedcode.com" . -R -n
忽略样式中的大小写
echo "HELLO" | grep -i "HELLO"
包括或者排除文件,只搜索所有的.c和 .cpp文件
grep "main" . -r --include *.{c,cpp}
排除.c和.cpp
grep "main" . -r --exclude *.{c,cpp}
排除目录
--exclude-dir
grep -q 静默输出,不会打印输出 会返回真假
打印匹配结果的之前或之后的行
seq 10 | grep 5 -A 3 #打印匹配后3行
之前用 -B
之前和之后 用 -C