读图书 Linux Shell 脚本攻略 门佳译 笔记
#!bin
运行脚本
1.bash script.sh
2.chmod a+x 赋予可执行权限 ./script.sh
for 循环
for var in list;
do
commands; 3使用变量var
done
list可以是个字符串也可以是个序列
echo {1..50} 能够生成1-50的数字列表
也可以使用 c语言是for循环形式
for((i=0;i<10;i++))
{
commands;#使用变量$i
}
while循环
while condition
do
commands;
done9
使用true则进行无限循环
until循环
x=0;
until [$x -eq ];
do
let x++;echo $x;
done
if语句
if condition;
then
commands;
fi
if condition;
then
commands;
else if condition ; then
commands;
else
commands;
fi
使用逻辑符号使其变的简洁些。
[condition] && action; #如果为真则执行action
[condition] || action; #如果为假则执行action
终端打印
echo 自动添加换行符
printf 手动添加换行符
[jz@localhost ~]$ echo -e "\e[1;31m this is red text \e[0m"
this is red text
彩色打印
0重置 30黑色 31红色 32绿色 33黄色 34蓝色 35洋红 36青色 37白色
环境变量:
脚本不需要在使用变量之前声明类型
每个变量的值都是字符串
赋值
var=value
如果value不包含任何空白字符(例如空格),那么它就不需要使用双引号进行引用。
#注意 var = value 是相等操作和赋值概念不同。
export 用来设置环境变量
使用''时 变量不会被扩展,依然会按照原样显示。
如果var已经被定义过了,"$var"将会打印出该值
获得变量的长度 length=${#var}
[jz@localhost ~]$ var=123456
[jz@localhost ~]$ echo ${#var}
6
echo $SHELL 识别使用的SHELL
检查是否是root用户
if [$UID -ne 0]; then
echo Non root user.Please run as root.
else
echo root user
fi
let 命令可以执行基本的算术运算 当使用let时 变量名前不需要再添加$
> 保存文件 >> 文件添加
当一个命令发生错误并退出时 它将返回一个非0的退出状态
当命令成功返回时,它会返回数字0。退出状态可以从$?中获得。
tee 接收来自stdin 的数据 将stdout的一份副本写入到out 同时将另一份副本作为后续的stdin
/dev/null 特殊的设备文件,接收的任何文件都将会被丢弃,null称为文件黑洞。到这里的数据将会一去不复返。
关联数组
可以使用任意的文本作为数组索引。
alias 设置别名的安全问题
将当前的别名进行转义,忽略当前定义的别名。
$ \command
字符 \ 对命令进行转义,使我们可以执行原来的命令而不是别名的替身。
在不可信的环境下执行特权指令,在命令前加\
-echo 禁止将输出发送到终端
bash -x s.sh #提供调试功能
set -x #执行时显示参数和命令
set +x #禁止调试,-x +x 对调试区域进行了限制
定义函数
function fname()
{
statement;
}
fname()
{
statement;
}
$fname; #只需要函数名就可以调用函数
fname arg1,arg2;#传递参数
echo "$@"; #以列表的方式一次性打印所有的参数。。
echo "$*"; #类似$@,但参数作为单个个体
递归函数
F()
{echo $1;
F hello;
sleep 1;
}
Fork 炸弹
:(){:|:&};:
导出函数,这样函数的作用域就可以扩展到子进程中
export -f fname
读取命令的返回值
cmd;
echo $?;
返回值为命令的退出状态,分析命令成功执行与否。成功退出,退出状态为0,否则非0;
cmd_output=$(COMMANDS) #读取由管道相连的命令的输出,成为子shell
如: cmd_output=$(ls | cat -n);
或者为反引用
cmd_output=`ls | cat -n`
echo $cmd_output
pwd
(cd /;ls)
pwd
结果:
/home/jz
bin dev home lib64 media opt root selinux sys usr
boot etc lib lost+found mnt proc sbin srv tmp var
/home/jz
当命令在子进程中执行时,不会对当前的子进程有任何影响,所有权的改变仅限于子shell中
read 输入语句
从输入中读取n个字符并存入变量variable_name中
read -n number_of_chars variable_name
例如
read -n 2 var
echo $var
read -s var #以无回显的方式读取密码
read -p “enter input” var #显示提示信息
read -t timeout var #在特定时限内输入
read -d ":" var #以特定边界符作为输入行的结束
运行命令直到成功
repat () {while :;$@ && return ; done}
条件比较一般放在中括号中[],注意在[或]与操作数间有一个空格,忘记该空格则报错
[$var -eq 0 ] or [ $var -eq 0 ]
对变量进行算数条件判断
[ $var -eq 0 ]
[ $var -ne 0 ] #不相同
逻辑与 -a
逻辑或 -o
可以进行文件系统的测试
[ -f $file_var ] 如果给定的变量包含正常的文件路径或文件名 则返回为真
-x 文件可执行
-d 目录
-e 文件存在
-c 字符设备文件的路径
-b 块设备的文件路径
-w 可写
-r 可读
-L 包含符号链接
##字符串比较 最好使用双引号
[[ $str1 = $str2 ]] 注意在两个[[间不能有空格
[[ $str1 == $str2 ]] 检查是否相等的另一种方法
检查不同
[[ $str1 != $str2 ]]
[[ $s1 > $s2 ]] s1的字母序比s2的大
[[ -z $s1 ]] 空串返回真
[[ -n $s1 ]] 非空返回真
grep awk find 使用
#cat 拼接
cat 删除多余的空白行
cat -s file #删除相邻的空白行
tr 删除所有的空白行
cat -T file #将制表符标记为^|
录制终端
[jz@localhost ~]$ script -t 2> timing.log -a putput.session
开始录制终端
[jz@localhost ~]$ scriptreplay timing.log putput.session
开始播放终端
find 使用
find 参数 -name 名称 -iname 忽略大小写
-o 或者
find . \(-name "*.txt" -o -name "*.pdf" \) -print
\\使将之间的内容视为整体
-path 匹配文件路径
find的否定参数
find . ! -name "*.txt"
find 搜索时会遍历所有的子目录,使用深度选择 -maxdepth or -mindepth
限制查找find命令遍历的目录数目
find . -maxdepth 1 -name "f*"
根据文件类型查找
find -type d 目录
f 文件
l 链接文件
根据时间查找
-atime 最后一次访问时间
-mtime 最后一次被修改的时间
-ctime 文件元数据(例如权限或所有权)被改变的时间
+大于 -小于 天数
打印最近7天被访问过的文件
find -type f -atime -7
find的漂亮特性 -newer 指定一个比较时间戳的参考文件,可以找出比参考文件新的所有文件。
[jz@localhost ~]$ find . -type f -newer s.sh
基于文件大小的搜索
find . type f -size +2k
b 块512 字节
c 字节
w 字
k 1024字节
M
G
-delete 删除find查找到的匹配文件
find . type f -name "*.swp" -delete
文件权限 -per 644
用户 -user
-exec find可以执行相关是命令
find . -type f -user root -exec chown jz {} \;
将root文件是所有权更改为jz
#xargs
将从stdin的数据重新进行格式化
统计源代码中c程序的行数LOC line of code
[jz@localhost ~]$ find ./code/ -type f -name "*.c" -print0 | xargs -0 wc -l
48 ./code/file.c
40 ./code/main.c
1935 ./code/inode.c
27 ./code/gdb_example.c
18 ./code/hello.c
2068 total
[jz@localhost ~]$
[jz@localhost ~]$ find ./code/ -type f -name "*.c" -print
./code/file.c
./code/main.c
./code/inode.c
./code/gdb_example.c
./code/hello.c
[jz@localhost ~]$
print0 以\0 作为结束符
[jz@localhost ~]$ find ./code/ -type f -name "*.c" -print0
./code/file.c./code/main.c./code/inode.c./code/gdb_example.c./code/hello.c[jz@localhost ~]$
tr 进行字符转换
将特定字符去掉
echo "hello 1234" | tr -d '0-9'
将数字删除
tr 压缩字符
-s
#校验
md5sun
sha1sum
对目录中的所有文件以递归的方式进行检查校验和
#加密与散列
crypt gpg base64 md5sum sha1sum openssl
创建任意大小的文件
dd if=/dev/zero of=out.out bs=1M count=1
#将一个文件设置为不可修改
chattr +i file
#sed进行文本替换 可以配合正则表达式使用 功能不同凡响
sed 's/pattern/replace_string/' file
替换所有的加上g
awk 进行高级文本处理 可以对行和列进行操作
匹配电子邮件 表达式
[jz@localhost ~]$ egrep -o '[A-Za-z0-9._]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}' email.txt
#wget web界面下载
可以像像网络爬虫一样,以递归的方式遍历网页上的所有URL链接,并且逐个下载形成镜像文件
可以将页面的地址转换为本地地址
wget --miior --covert-links www.nwpu.edu.cn
wget -r -N -k -l 2 www.nwpu.edu.cn
-r 使用递归的方式
-N 使用文件的时间戳
-k 或 -convert-links 指示将页面的连接地址转换为本地的地址
-l 下载的层级数
#跟踪网站变动,变动跟踪器
第6章
rsync在备份时,
1)部分,将文件排除
2)将在源端不存在的文件删除
3)压缩提高传输效率
4)定期进行备份
git进行版本控制的备份
fsarchiver 将整个文件系统,保存为一个压缩形式的归档文件
同时对文件系统进行了备份
第7章 无网不利
logrotate 管理日志文件
syslog 在linux系统中通过 守护进程syslog 创建日志文件。