shell脚本编程基础知识一
使用多个命令
在shell中可以输入多个命令,并输出不同命令的结果。甚至可以将一个命令的输出结果传递给另一个命令,可以将多个命令串联起来,一次执行完毕,而不是单独输入多次单个命令去执行。
如果想要多个命令一起执行,可以用;
分号进行隔开,这样就能让多个命令随意串联在一起使用,但是需要注意命令行最大字符数是255
,也就是说在终端命令行窗口中,最多只能输入255
长度的命令。
date;who#Sun May 4 09:34:56 CST 2025#xiaobei console Apr 29 22:23#xiaobei ttys002 May 4 09:34
创建shell脚本
创建shell脚本文件时,需要注意必须在文件的第一行指定要使用的shell,格式如下:
#!/bin/bash
在普通的shell脚本中#
是用于注释,shell并不会处理脚本中的注释,但是shell脚本文件的第一行是个例外,#
后面的惊叹号会让shell知道使用那个shell来运行脚本。
常见的shell有:
- bash
- zsh
- fish
- powershell
命令替换符号
bash中有2种方式,可以从命令输出中提取信息并赋值给bash变量。有如下两种形式:
- 反引号(`)
- $()
举例:
testing=`date`# 2025年 5月 4日 星期日 01时02分05秒 CST
# 或者方式testing=$(date)
需要注意:赋值符号与替换符号之间不能有空格
重定向输入和输出
作用是将命令的输出重定向到其他位置(比如文件)。重定向即可以用于输入,也可以用于输出,比如:将文件中的内容重定向为命令的输入。
输出重定向
语法:command > outputfile
使用大于符号>
来实现输出重定向,例如:将ls -al
命令的结果输入到test.txt
文件中。
date > test.txt
# cat test.txt#2025年 5月 4日 星期日 01时20分26秒 CST
注意:大于符号>
每次都会将文件的内容进行覆盖。
who > test.txt
#cat test.txt#xiaobei console 5 4 00:51#xiaobei ttys000 5 4 01:01
如果你不想覆盖原来文件中的内容,而是在原来文件中进行内容的追加,则需要使用>>
双大于符号来表示。
举例:
date >> test.txt
#cat test.txt#xiaobei console 5 4 00:51#xiaobei ttys000 5 4 01:01#2025年 5月 4日 星期日 01时26分24秒 CST
输入重定向
输入重定向是将文件的内容重定向到命令,输出重定向是命令的结果输出到文件,输入重定向是文件内容输出给命令。
语法:command < outputfile
使用小于符号<
来实现输入重定向。与输出重定向的>>
类似,也有<<
内联输入重定向。
两者可以根据符号的方向来记忆到底是输出重定向还是输入重定向,因为两者的共性都是以命令开头,可以把输出重定向的大于符号>
,看作是一个箭头符号,表示数据从命令流向到文件。输入重定向则反过来记忆,<
就表示文件内容流向到命令。
管道
不知道你有没有遇到过这种情况,就是需要将一个命令的输出结果作为另一个命令的输入,按照上面说的,我们可以使用重定向来实现,但是会显得很笨拙,显得很啰嗦。
例如:
rpm -qa > rpm.listsort < rpm.list
将rpm命令 + -qa参数,会生成使用rpm包管理器安装包的列表,但是这个列表并不是遵循某种特定的顺序,需要要找到具体某个rpm包是不太好找的。先通过重定向,将所有安装的rpm包使用输出重定向到rpm.list文件中,然后通过输入重定向,将rpm.list文件中的内容传递给sort命令对其进行排序,由sort命令按字母顺序对rpm包名称进行排序。
这种方式虽然管用,但是这个过程还是比较繁琐,又要重定向又要生成缓冲文件的,那有没有一种更简单方式?答案是有的,那就是使用管道。
什么是管道呢?管道一种将多个命令连接起来的机制,允许将一个命令的输出(stdout)直接作为另一个命令的输入(stdin),它通过符号|
表示,是命令行操作中极其强大的工具。简而言之就是可以用来连接多个linux命令的。
管道能干什么呢?常见的管道操作场景如下:
- 过滤数据
# 查看当前目录下所有 ".txt" 文件ls -l | grep ".txt"
ls
列出文件,grep
筛选出包含 “.txt” 的行。
- 统计信息
# 统计日志文件中 "ERROR" 出现的次数cat app.log | grep "ERROR" | wc -l
cat
读取日志,grep
过滤关键字,wc -l
统计行数。
- 排序去重
# 对文件中的内容排序并去重cat data.txt | sort | uniq
sort
排序,uniq
去重(需先排序)。
- 进程管理
# 查找并强制结束名为 "chrome" 的进程ps aux | grep "chrome" | awk '{print $2}' | xargs kill -9
ps
列出进程,grep
筛选目标,awk
提取进程ID,xargs
传递参数给 kill
。
- 实时监控日志
# 实时跟踪日志并过滤关键信息tail -f /var/log/syslog | grep "Failed"
tail -f
持续输出日志内容,grep
过滤特定关键词。
- 数据转换
# 将当前目录文件大小转换为 MB 显示du -sh * | awk '{print $1/1024 " MB"}'
du
获取文件大小,awk
转换单位。
那上诉的案例重写如下:
rpm -qa | sort
是不是看起来都比上面的那种写法清爽很多。
管道可以连接的命令数量没有限制,可以持续的将命令的输出通过管道传递给其他命令来细化操作。
例如:
rpm -qa | sort | more
命令的含义,先执行rpm
命令,将命令输出的结果传递给sort
,然后sort
命令排序好后,将排序好的顺序输出给more
命令显示。
也可以结合输出重定向,将排序好的结果存到对应文件中。
rpm -qa | sort > rpm.list