shell脚本执行方式
- shell脚本就是将linux命令放入文本文件中,由解释器执行;
- bash解释器执行
sh lauf.sh
- 自己执行
- 必须以#!/bin/bash 开头;
- 必须具有可执行权限;
# 修改权限
chmod u+x lauf.sh
# 执行
./lauf.sh
其本质还是使用文件开头的/bin/bash 解释器执行的。
常用符号及命令
- 命令行提示符以$结尾,表示普通用户;以#结尾表示root用户(最高权限);脚本中#表示注释,同python
- 查看当前shell版本 -> $SHELL or $0
- root用户id 为0 -> echo $UID
- PS1 变量表示命令提示符内容,如PS1=“\e\u@\h~\w”
- 打印输出
- echo 输出并自动换行
- printf 输出且不换行
# 输出字符串并换行,后面的内容均当做字符串
echo hello world
# 输出且不换行
echo -n "hello world"
# 输出带有转义的字符
echo -e "\t\n"
# 带有颜色的输出
echo -e "\e[1;42m hello world \e[0m"
# printf 同C语言中printf()
printf "%-20s\n" jack
# %4.2f -表示左对齐 默认右对齐 宽度不够空格补
# %d
-
查看文件内容
- cat lauf.sh 查看内容
- head lauf.sh 查看开头
- tail -f lauf.sh 查看结尾
- vim lauf.sh 编辑文件
- touch lauf.sh 创建文件
- ls -l lauf.sh 查看文件详情
-
替换文本
- tr , echo xxx | tr “a” “b” 将内容中的a替换为b,短补充、长截取
- tr “a-z” “A-Z” 小写集合内替换为大写集合内对应的字符
- echo 12345 | tr “0-9” “9876543210” -> 87654
- 第二个集合不能为空串
- 类似 tr “[:lower:]” “[:upper:]”
- tr -d " \n" 删除空格、\n
- tr -d -c “0-9” 删除集合以外的字符
-
算术运算
- let result=a+b; let a++;
- result=$[a+b]
- result=$((a+b))
- expr 声明表达式,使用let继续运算
- echo “2*0.5” |bc 浮点数运算
- echo “scale=2;5/6”|bc 保留两位小数
- echo “obase=2;$num”|bc 转二进制
- echo “sqrt(100)”|bc
- echo “2^3”|bc
-
文件描述符
- 与已打开文件或者数据流相关的整数,是访问文件的指针;
- 0 标准输入 ;1 标准输出; 2标准错误输出 -->系统预留
- echo “hello world” > out.txt 标准输出重定向
- echo “xxxx” >> out.txt 标准输出追加重定向
- ls + 2>error.txt 1>log.txt 标准错误重定向与标准输出重定向
- ls + >log.txt 2>&1 标准错误 重定向到标准输出
- ls + 2>/dev/null 丢弃标准错误
- tee重定向到文件,并交给管道; echo xx | tee -a out.txt | cat - file.txt
- cmd < file 文件内容重定向到命令
- cat << EOF>log.txt 将脚本中当前位置到"EOF"位置之间的内容重定向到文件中
- 自定义文件描述符,exec 3<file 读取;exec 4>file 写入;exec 5>>file; echo xxxx >&4 写入;
-
文件校验和
- md5sum file1 file2 … >xxx.md5 生产对应文件的校验和
- md5sum -c xxx.md5 校验文件是否损坏
- 案例,找个当前目录下的所有的C文件,生成校验和,并追加到c.md5文件
find . -type f -name "*.c" -print0 |xargs -0 md5sum >> c.md5
-
排序
- sort 排序, 常结合uniq一起使用
- sort -n file.txt 数字方式排序【默认第一列】
- sort -k 2 file.txt 指定列排序
- sort -r file.txt 逆序排序
- sort -d file.txt 字典序排序
- sort -u file.txt 排序后去重 -b 忽略前导空白符
- cat file.txt | sort -k 3 | uniq -c 去重并统计重复的行数
- uniq -d 找出重复的行; -s 2 跳过指定字符数;-w 2 判断重复时比较的最多字符数; -z 以\0作为定界符
-
find 递归查找文件
- linux系统中一切皆文件;
- 文件的类型,f 普通文件、d目录、l 链接文件、c字符设备、b块设备、s套接字
- 使用 find ./ -maxdepth 3 -type f -name “*.txt” -print
- -maxdepth 递归查找的最大深度
- -mindepth 最小深度
- -type 文件类型
- -name 匹配名称; ! -name条件否定
- -iname 忽略大小写匹配名称
- -path 匹配整个文件路径
- -regex 简单正则匹配整个路径 find ./ -type f -regex “.*seq.*” -print;字母不开头
- -atime 最近一次访问时间,天
- -mtime 文件内容最近一次修改时间,天
- -ctime 文件元数据最近一次修改时间,天
- -amin、-mmin、-cmin 分钟
- find . -type f -name “*.c” -atime 7 等于7天
- find . -type f -name “*.c” -atime +7 大于7天
- find . -type f -name “*.c” -atime -7 小于7天
- -size 20k、 大于+20k、 小于 -20k 根据大小查找 M G c字节 b 块(512bytes)
- -perm 644 根据权限查找
- -print 打印输出
- -print0 以 \0 作为定界符
- -delete 删除查询结果
- -exec 执行操作,只能一个命令,多个命令放入sh脚本
- find . -maxdepth 2 -type f -user lauf -name “*.txt” -exec chmod u+x {} \;
- 删除多个目录,find . -type d -name “*pycache*” -exec rm -rf {} \; 也通过xargs 转为命令行参数进行删除;
- 解析,大括号{}替换为每个文件,\; 必须是一个反斜杠+分号
- -exec cat {} \; >out.log
- -exec cp {} target_dir \;
- -exec ./lauf.sh {} \;
- -prune裁剪 跳过指定的目录 find . \(-name “dir" -prune \) -o \(-type f -path ".c” -print \)
-
命令行参数
-
使用xargs 将输入内容转为命令行参数(一行),传给一个命令
-
echo -e “jack\n tom\n lucy” | xargs 默认的定界符为 空格,-d 指定定界符
- [laufing@centos ~]$ echo “jack,tom,lucy” |xargs -d ,
jack tom lucy
- [laufing@centos ~]$ echo “jack,tom,lucy” |xargs -d ,
-
echo -e “jack\n tom\n lucy” | xargs -n 2 ./lauf.sh 转为两个参数,依次传给脚本
-
xargs -I {} ./lauf.sh -p {} 替换传参
-
find . -type f -name “*.py” -print0 | xargs -0 rm -f 删除每个文件
-
find . -type f -name “*.py” -print0 | xargs -0 wc -l 统计每个文件行数
- 5 ./lauf.sh
-
-
修改文件权限
- chmod u=rwx g=r o=r lauf.sh
- u 当前用户
- g 文件所属用户组
- o 其他用户
- a 所有用户
- chmod a+x lauf.sh 所有用户添加可执行权限
- chmod u-wx lauf.sh 当前用户去除写、可执行权限
- ls -la 列出所有的文件及信息
- -rw-rw-r–. 1 laufing laufing 3 Sep 13 06:36 c1.c
-rw-rw-r–. 1 laufing laufing 3 Sep 13 06:36 c2.c
-rw-rw-r–. 1 laufing laufing 82 Sep 13 06:44 c.md5
drwxr-xr-x. 2 laufing laufing 72 Mar 25 03:32 Desktop
drwxr-xr-x. 2 laufing laufing 6 Mar 25 01:56 Documents - 三组权限u g o、软连接数、用户、用户组、大小bytes、时间、文件名
- -rw-rw-r–. 1 laufing laufing 3 Sep 13 06:36 c1.c
- chmod u=rwx g=r o=r lauf.sh
变量
- 普通变量
- 声明变量,直接赋值,同python
- =两边
不能有空格 - ‘’ 单引号表示纯字符
- “”双引号表示一个整体
- ``反引号表示操作命令
- 末尾没有;号
- 变量的值均为字符串
- 使用$变量 获取值
- ${#变量} 获取字符串值的长度
# 直接赋值,
name='jack' # 纯字符
pyCode='import os\nimport csv\n xxxx'
# -e 识别转义字符,输出到文件中
echo -e $pyCode > content.txt # $符引用变量的值
state="name is jack, current dir $(pwd)" # 必须带括号
echo -e $state >> content.txt
- 环境变量
- 配置环境变量,以使linux操作系统可以使用。
当前用户下的环境变量
# 编辑文件
vim ~/.bashrc
# 配置环境变量
export PATH=$PATH:/home/xxx/py
export LD_LIBRARY_PATH=XXXX
# 保存后,使用变量生效
source ~/.bashrc
全局的环境变量
# edit
vim /etc/profile
# config
export PATH=$PATH:/home/xxx/py
# enable
source /etc/profile
- 命令行变量
- shell 脚本命令行
- 函数的参数
# 执行shell脚本,传参
$ sh laufing.sh param1 param2
# 脚本中使用$1 $2 ....$9..${10}
# 获取参数个数 $#
# 获取所有的参数 $* / $@
# $?上一条指令的执行结果 0表示成功
# 定义函数 类js
function func(){
echo $1
echo $2
}
# 执行函数
func param1 param2
分支
- test xxx,表示测试条件,成功返回true
- 数值比较
- -eq 等于
- -gt 大于
- -lt 小于
- -ge 大于等于
- -le 小于等于
- 字符串比较
- = or == 相同
- != 不同
- -z 长度为0 返回true
- -n 长度非0 返回true
- 文化目录的判断
- -e 文件或者目录是否存在
- -f 存在且为文件
- -d 存在且为目录
- -r 文件存在且可读
- -w 文件存在且可写
- -x 可执行
# test判断语句 可避免多层括号
if test 5 -gt 3;then
echo "true"
fi # 结束
# [] 表示 数值 测试语句,必须有空格
# [[ ]] 字符串 测试语句 必有空格
if [[ $1 = '' ]];then
echo "no params"
elif [[ $1 = 'lauf' ]] || [[ $1 = 'tom' ]];then
echo "lauf or tom params"
else
echo "other params"
fi
# 简化判断 上个指令执行成功时,才进入指定目录
[ $? -eq 0 ] && cd lauf
&& || 连接多个测试条件,
! 条件内部取反
循环
# 循环 数值序列, 闭区间
for i in {1..5};do
echo $i
done
# 遍历字符串
IFS=";" # 设置内部字段分隔符
for i in "jack;lucy;lili"
do
echo $i # jack lucy lili 整体
done
# 变量目录下的文件
curDir=`ls $(pwd)` # 数组
for i in $curDir # 引用数组
do
echo $i
done
# 通配符 匹配结果
for i in *.jpg *.png; # 1 2 3 数组
do
echo $i
done
函数
shell定义函数特别简单,类似js。
function func1(){
echo $1 # 打印第一个参数
echo $# # 总参数个数
echo $@ # 所有参数数组 可循环遍历
}
func2(){
echo "func2"
}
# 函数调用,并传参
func1 "tom" 4
函数案例
递归实现每个目录下添加文件。

创建lauf.sh脚本
#!/bin/bash
function addFile(){
if [ -d $1 ];then
echo "add file for $1"
touch "$1/lauf.txt"
# recursive
dealDir $(pwd)/$1
fi
}
function dealDir(){ # need absolute path
cd $1
curFiles=`ls $1`
for i in $curFiles;do
addFile $i
done
}
# sh lauf.sh /home/laufing/aa
dealDir $1
本文介绍了Shell脚本的执行方式,包括如何赋予脚本执行权限以及通过bash解释器运行。接着,详细讲解了常用的命令和符号,如echo、printf、cat、find等,以及变量的声明和使用。此外,还涉及到了条件判断、循环结构以及函数的定义和调用。文章通过实例展示了如何在Shell脚本中进行文件操作和权限管理,并提到了文件校验和的计算方法。
2405

被折叠的 条评论
为什么被折叠?



