shell脚本编程——使用Linux
Linux系统环境
文件系统结构
一切皆文件。
分为四个主要部分:内核、shell、文件系统和应用程序
内核是操作系统的核心,具有很多最基本功能,负责管理系统进程、内存、设备驱动程序、文件和网络系统,决定系统性能和稳定性
shell是一种应用程序,为用户提供操作界面,是用户与内核交互操作的接口。
内核、shell和文件系统一起形成了基本的操作系统结构,使得用户可以运行程序、管理文件并使用系统
#shell也是一门编程语言(脚本编程)
#查看CPU信息:
lscpu #查看内存信息: free -h #查看硬盘信息: df -h #查看文件大小: du -h -d 1 du -sh ~ #总结 #查看系统进程与应用: top #任务管理器 htop #top的升级版,需要用conda进行安装。#可查看每个核使用情况。#axel:多线程下载工具,也需要用conda进行安装 ps -ef jobs #只在命令运行的当前窗口起效
变量
环境变量、位置参数变量、状态变量、自定义变量,调用时须在变量前加$
环境变量
用于储存有关shell会话和工作环境的系统变量
常见环境变量:
HOME:当前用户的主目录
PATH:shell查找命令的目录列表,由:分隔
SHELL:bash shell的全路径名
LOGNAME:当前用户的登录名
PS1:shell命令行界面的主提示符
位置参数变量
用于向命令或程序脚本中传递信息
$n:n为数字,$0代表命令(脚本)本身,$1~$9代表第1~9个参数,10以上的参数需要用大括号包含,如${10}
$* :代表命令行中所有参数,把所有参数看成一个整体
$@:也代表命令行中所有参数,不过$@把每个参数区别对待
$#:代表命令行中所有参数的个数
#参数传递的优点
1 灵活性
2 可重用性
3 减少错误
#应用
写好一个脚本,然后将文件插入到脚本中对应参数的位置即可运行脚本
状态变量
用于记录命令的运行结果
$?:获取执行上一个指令的执行状态返回值,0代表上一个指令执行成功,否则为执行失败
$$:获取当前执行的shell脚本的进程号PID
$!:获取上一个后台工作的进程的进程号PID
$_:获取在此之前执行的命令或脚本的最后一个参数
自定义变量
由用户自行定义的变量,可用于用户编写的脚本,多个命令间的值传递等。
#等号前后不要加空格
例:
a=gene 比较: echo a --> a echo $a --> gene echo 'This is a $a' --> This is a $a echo "This is a $a" --> This is a gene #单引号中的变量不会被解释 #双引号中的变量会被解释 #外层引号决定,可使用转义字符防止变量展开
结构化语句
条件语句if
常见格式1:
if command ##条件 then commands fi
常见格式2:
if command then commands else commands fi
常见格式3:
if command1 then commands else if command2 then commands else commands fi fi
常见条件
数值判断、字符串判断、文件判断
数值判断
用法: INT1 -eq INT2
-eq #相等 -nq #不相等
-gt #大于 -lt #小于
-ge #大于等于 -le #小于等于
##可在两行命令间加“;”将两行命令并成一行,两句命令不存在关系;也可以使用“&&”,则两句命令相关,只能同时运行或不运行
##“||”为逻辑值或,可以运行两句命令中的一句
字符串判断
-z STRING #字符串长度是否为0,即是否为空
-n STRING #字符串长度是否非0,即是否非空
STRING1 #字符串是否不为空,与-n类似
STRING1 == STRING2 #两字符串是否相同
STRING1 != STRING2 #两字符串是否不同
STRING1 < STRING2 #若字符串1的字典排序在字符串2前面则返回TRUE,> 同理
文件判断
-a FILE #文件是否存在
-d FILE #文件是否存在且为目录
-f FILE #文件是否存在且为普通文件
#!:取反,例
if ! -f ok.txt ##检查是否存在ok.txt,若不存在则创建该文件 then touch ok.txt fi
循环语句for和while
for循环常见格式
for i in list do commandsundefineddone #命令中变量应加{},否则无法识别变量,如:${i}, ${list}
示例1
for i in {1..10} do touch file${i} done
示例2
for i in $(ls file*) do mv ${i} ${i}.txt #更改后缀名 done
while循环常见格式
常见格式1:不常用
while command do other commands done
常见格式2:
while read id ##id为形式参数 do commands done
示例1
ls file* | while read id do mv ${id} ${id}.txt done
示例2
ls file* > config cat config | while read id do mv ${id} ${id%.txt} ##去除后缀名.txt done
示例3
cat config | while read id do mv ${id} ${id%.*} ##去除所有文件的最后一个后缀名 done
参数扩展
作用:掐头去尾
${变量#关键词} #若变量头部数据符合关键词,则将符合的最短数据删除
${变量##关键词} #若变量头部数据符合关键词,则将符合的最长数据删除
${变量%关键词} #若变量尾部数据符合关键词,则将符合的最短数据删除
${变量%%关键词} #若变量尾部数据符合关键词,则将符合的最长数据删除
作用:替换
${变量/旧字符串/新字符串} #若变量内容符合旧字符串,则替换首个旧字符串
${变量//旧字符串/新字符串} #若变量内容符合旧字符串,则替换全部旧字符串
shell脚本编程
为了与普通文本区分开,通常都以.sh为后缀名
脚本首行的 #! 是Linux的Shebang符号,指定解释器
其它脚本:
在Linux中使用其他编程语言,需要在shebang中定义解释器。
Python是python/python2/python3,R语言是Rscript,可用which命令找到解释器位置
Shebang扩展
如何解决不同平台或不同设备下的差异
shebang的通用写法:
#!/usr/bin/env bash #!/usr/bin/env python #!/usr/bin/env Rscript ##env的位置相对固定,使用env去调用当前环境下的解释器
shell脚本
修改文件权限后可直接通过路径调用(充当command)
保存运行日志
bash test.sh 1>test.log 2>&1 #1:标准输出流。2:标准误输出流
示例
##写三句命令,两句正确一句错误
vim test.sh cat test.sh pwd pwd ppp
##1 不进行重定向,结果直接输出到标准输出流(屏幕)
bash test.sh /trainee/Last30 /trainee/Last30 test.sh: line 3: ppp: command not found
##2 进行重定向,但不指定标准输出和标准误输出,正确的在out.log中,错误的输出到标准输出流(屏幕)
bash test.sh > out.log test.sh: line 3: ppp: command not found
##3 进行分开重定向,正确与错误分别进入两个log文件
bash test.sh 1>out.log 2>error.log cat out.log /trainee/Last30 /trainee/Last30 cat error.log test.sh: line 3: ppp: command not found
##4 进行分开重定向,将2输出到1中,两者都输出至out.log
bash test.sh 1>out.log 2>&1 cat out.log /trainee/Last30 /trainee/Last30 test.sh: line 3: ppp: command not found
任务提交重点
nohup #不要挂断任务,把任务提交至服务器上运行
& #任务后台运行,通常与nohup连用 #nohup bash file.sh > file.log &
top #实时显示系统冲各个进程的资源占用情况,按q退出
htop #优化过的top
ps #Process Status列出当前系统中运行的进程列表,一般加-ef参数,搭配grep进行搜索:ps -ef | grep <USERNAME>
kill #结束进程:kill -9 PID #强制终止进程
tail -f <log file> #浮动查看file.sh进程
less -SN <log file> #用less动态查看。 #Shift F
jobs #仅能查看当前会话中运行的命令
引用自生信技能树