Linux6-shell脚本编程
Linux基础课程系列:
1. Linux系统环境
1.1 Linux系统的4个主要部分:内核
、shell
、文件系统
和应用程序
。
内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。
• 内核
是操作系统的核心,具有很多最基本功能,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性,识别的是0和1。
• shell
是系统的用户界面,提供了用户与内核进行交互操作的一种接口。相当于一个翻译官,将我们输入的命令翻译成如010101这样的内核可以识别的格式传递给内核。内核调用后再通过shell传递给我们。
• shell也是一门编程语言(脚本语言)
1.2 Linux文件系统结构:一切皆文件
/
:虚拟目录的根目录。通常不会在这里存储文件
/bin
:二进制目录,存放许多用户级的GNU工具(cp, mkdir, rm, cat, echo等命令都存在这里)
/boot
:启动目录,存在启动文件
/dev
:系统配置文件目录
/ect
:系统配置文件目录
/home
:主目录,Linux在这里创建用户目录
/lib
:库目录,存放系统和应用程序的库文件
/media
:媒体目录,可移动媒体设备的常用挂载点
/root
:root用户的主目录
/sbin
:系统二进制目录,存放许多GNU管理员级工具
/run
:运行目录,存在系统运行时的运行时数据
/tmp
:临时目录,可以在该目录中创建和删除临时工作文件
/usr
:用户二进制目录,大量用户级的GNU工具和数据文件都储存在这里
1.3 Linux系统环境
• 查看CPU信息:lscpu
• 查看内存信息:free -h
• 查看硬盘信息:df -h
• 查看文件大小:du -h -d 1
(-d 1是只展开第一层的意思,也就是只看该目录下的文件/文件夹大小,而不必显示文件夹中的文件/文件夹大小)
• 查看文件大小:du -sh ~
• 查看系统进程:top
(ctrl+c暂停,q退出),htop
(看的是所有人的进程,可以使用htop -u
用户名查看某用户的进程)或者ps -ef | grep "$LOGNAME"
服务器最重要的三大件:CPU(决定运算速度),内存(决定命令能否运行),存储(决定存储文件多少)
内存和存储的作用区别:内存是一种用于暂时存放CPU中的运算数据和外部储存器交换数据的随机储存器,读写速率极高,充当外部储存和CPU沟通桥梁的角色。由于硬盘速度有限,为了提高处理速度,操作系统会预先将需要运算的数据由硬盘调取至内存,以便CPU快速调取数据进行运算。储存是用于存放数据的,一般常见的机械硬盘和固态硬盘都是储存硬件。
2. 变量
变量包括环境变量、状态变量、位置参数变量和自定义变量。
调用变量时,要在变量前面加一个$
符号 (定义的时候不需要)
2.1 环境变量:用于存储有关shell会话和工作环境的系统变量
常见环境变量:
• $HOME
:当前用户的主目录
• $PATH
:shell查找命令的目录列表,由冒号(:)分隔。(输入命令时Linux会去查找PATH里面记录的路径)
• $SHELL
:bash shell的全路径名
• $LOGNAME
:当前用户的登录名。和whoami
命令的输出是一样的
• $PS1
:shell命令行界面的主提示符
查看环境变量
• echo
①打印字符串②打印变量的值,变量调用要加$
echo $PATH | tr ':' '\n'
~/.bashrc
:该文件包含专用于你的bash shell的bash信息,
当登录时以及每次打开新的shell时,该文件被读取和执行。
2.2 位置参数变量:用于用于向命令或程序脚本中传递信息
位置参数变量 | 作用 |
---|---|
$n |
n 为数字,$0 代表命令本身,$1~$9 代表第1~9 个参数,10 以上的参数需要用大括号包含, 如${10} |
$* | 这个变量代表命令行中所有的参数,把所有的参数看成一个整体 |
$@ | 这个变量也代表命令行中所有的参数,不过$@ 把每个参数区别对待 |
$# | 这个变量代表命令行中所有参数的个数 |
2.3 状态变量:用于记录命令的运行结果
状态变量 | 作用 |
---|---|
$? |
获取执行上一个指令的执行状态返回值,返回0表示上一个命令或者程序执行成功,返回的值为非0则表示上一个命令执行失败。 |
$$ | 获取当前执行的shell脚本的进程号PID。 |
$! | 获取上一个后台工作的进程的进程号PID。 |
$_ | 获取在此之前执行的命令或脚本的最后一个参数。 |
2.4 自定义变量:由用户自行定义的变量,可用于用户编写的脚本,多个命令间的值传递等
自定义变量时,等号两边一定不能加空格。
(base) lh@localhost ~ % a=gene
(base) lh@localhost ~ % echo $a
gene
(base) lh@localhost ~ % echo 'This is a $a'
This is a $a
(base) lh@localhost ~ % echo "This is a $a"
This is a gene
(base) lh@localhost ~ %
单引号:变量不会被解释
双引号:变量被解释
3. 结构化语句
3.1 条件语句if
- if 条件语句的常见格式:
❗️注意:if后面写每个元素都要加空格,否则会报错。例如:if [ 1 -eq 1 ]
,if和[之间,[和1之间,1和-eq之间,-eq和1之间,1和]之间,都需要空格。
- if 条件语句的常见条件:数值判断、字符串判断、文件判断
数值判断(使用较多)
用法 | 解释 |
---|---|
[ INT1 -eq INT2 ] | INT1和INT2两数相等(equal)返回为真 |
[ INT1 -ne INT2 ] | INT1和INT2两数不等(not equal)返回为真 |
[ INT1 -gt INT2 ] | INT1大于INT2(great than)返回为真 |
[ INT1 -ge INT2 ] | INT1大于等于(great equal)INT2返回为真 |
[ INT1 -lt INT2 ] | INT1小于INT2(less than)返回为真 |
[ INT1 -le INT2 ] | INT1小于等于INT2(less equal)返回为真 |
if [ $? -eq 0 ]
then
touch ok.txt
fi
#如果上一条命令执行成功,生成ok.txt文件
字符串判断(使用较少)
用法 | 解释 |
---|---|
[ -z STRING ] | 如果STRING的长度为零则返回为真,即空是真 |
[ -n STRING ] | 如果STRING的长度为非零则返回为真,即非空是真 |
[ STRING1 ] | 如果字符串不为空则返回为真,与-n类似 |
[ STRING1 == STRING2 ] | 如果两个字符串相同则返回为真 |
[ STRING1 != STRING2 ] | 如果两个字符串不相同则返回为真 |
[ STRING1 < STRING2 ] | 如果STRING1字典排序在STRING2前面则返回为真。>同理。 |
文件判断
用法 | 解释 |
---|---|
[ -a FILE ] | 如果FILE存在则为真 |
[ -d FILE ] | 如果FILE存在且是一个目录则返回为真 |
[ -f FILE ] | 如果FILE存在且是一个普通文件则返回为真 |
3.2 循环语句for 和while
- for循环
for i in list
do
commands
done
变量要加{},否则容易分辨不出变量
for i in {1..10}
do
echo ${i} 'Hi!'
sleep 3s
done
list="CDS exon gene start_codon stop_codon UTR"
for i in ${list}
do
echo "This feature is ${i}"
done
- while循环
#不常用
while command
do
other commands
done
#⚠️常用
while read id
do
commands
done
这里read后面的的id只是一个代号,也可以是任意的x、y、i等字符
3.3 参数扩展
作用:#掐头*去尾
参数扩展 | 含义 |
---|---|
${变量# 关键字} |
若变量内容从头开始的数据符合“关键字”,则将符合的最短数据删除 |
${变量## 关键字} |
若变量内容从头开始的数据符合“关键字”,则将符合的最长数据删除 |
${变量% 关键字} |
若变量内容从尾开始的数据符合“关键字”,则将符合的最短数据删除 |
${变量%% 关键字} |
若变量内容从尾开始的数据符合“关键字”,则将符合的最长数据删除 |
${变量/旧字符串/新字符串} | 若变量内容符合“旧字符串”,则首个旧字符串会被新字符串替换。 |
${变量//旧字符串/新字符串} | 若变量内容符合“旧字符串”,则全部旧字符串会被新字符串替换。 |
${变量:索引} | 截取变量从索引位置到末尾的所有字符 |
${变量:索引:n} | 截取变量从索引位置开始的n个字符 |
${变量:索引:(-n)}/ ${变量:索引:-n} | 截取变量从索引位置到倒数第n+1位的/所有字符 |
id=example.test.fq
echo $id
# example.test.fq
echo ${id#*.} ##从前往后,删除第一个.前面的内容
# test.fq
echo ${id##*.} ##从前往后,删除最后一个.前面的内容
# fq
echo ${id%.*} ##从后往前,删除第一个.后面的内容
# example.test
echo ${id%%.*} ##从后往前,删除最后一个 .后面的内容
# example
4. Shell脚本编程
- Shell脚本
shell 脚本:为了和普通文本文件区分开,通常shell脚本都会以.sh
为后缀名
Shell脚本书写规范:
脚本首行的#! 是Linux的Shebang符号(释伴),指定解释器。#! /bin/bash就是这个文件要用bash来解释。比如要写一个R脚本,可以先使用which R查看一下R命令的位置,在写脚本是写在#!之后即可。写python等脚本同理。
vim test.sh #书写脚本
bash test.sh 1>test.log 2>&1
#1:标准输出流;2:标准误输出流
cat test.log
- shell脚本的文件权限
chmod
修改shell脚本的文件权限后,可以全路径调用 - 参数传递
- 任务提交
•nohup
:不要挂断任务,即把任务提交到服务器上运行
•&
:任务后台运行,通常与nohup 连用
•top
:实时显示系统中各个进程的资源占用状况,按q 退出
•ps
:Process Status列出当前系统中运行的进程列表,一般加上–ef 参数
•kill
:杀掉进程,kill PID
更多参考:
https://wangdoc.com/bash/intro.html
https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/104.html