Linux命令行与shell脚本编程大全-2.2

news2024/7/6 18:44:01

第二部分 shell脚本编程基础

第11章构建基础脚本
第12章结构化命令
第13章更多的结构化命令
第14章处理用户输入
第15章呈现数据
第16章脚本控制

第15章 呈现数据

15.1 理解输入和输出

15.1.1 标准文件描述符

Linux 系统会将每个对象当作文件来处理,这包括输入和输出。Linux 用文件描述符来标识
每个文件对象。

15.1.2 重定向错误 #

15.2 在脚本中重定向输出

15.2.1 临时重定向

如果你有意在脚本中生成错误消息,可以将单独的一行输出重定向到STDERR。这只需要使
用输出重定向符号将输出重定向到STDERR 文件描述符符。在重定向到文件描述符时,必须在文件描述符索引值之前加一个&
echo "This is an error message" >&2
这行会在脚本的STDERR 文件描述符所指向的位置显示文本。

$ cat test10
#!/bin/bash
# redirecting all output to a file
exec 1>testout
echo "This is a test of redirecting all output"
echo "from a script to another file."
echo "without having to redirect every individual line"
$ ./test10
$ cat testout
This is a test of redirecting all output
from a script to another file.
without having to redirect every individual line
$
15.2.2 永久重定向: exec 命令

如果脚本中有大量数据需要重定向,那么逐条重定向所有的echo 语句会很烦琐。这时可以
用exec 命令,exec 命令会启动一个新shell 并将STDOUT 文件描述符重定向到指定文件。脚本中送往STDOUT 的所有输出都会被重定向

15.3 在脚本中重定向输入

在Linux 系统中,exec 命令允许将STDIN 重定向为文件:
exec 0< testfile

15.4 创建自己的重定向

15.4.1 创建输出文件描述符

可以用exec 命令分配用于输出的文件描述符

exec 3 > test13out

15.4.2 重定向文件描述符

exec 3>&1   # 将文件描述符3 重定向到了文件描述符1(STDOUT)的当前位置,

将发送给STDOUT 的输出直接送
往该文件。

$ cat test14
#!/bin/bash
# storing STDOUT, then coming back to it
exec 3>&1   # 将文件描述符3 重定向到了文件描述符1(STDOUT)的当前位置
exec 1>test14out   # 将STDOUT 重定向到了test14out文件
echo "This should store in the output file"
echo "along with this line."
exec 1>&3 #令将STDOUT 重定向到了文件描述符3 的当前位置
echo "Now things should be back to normal"
$
$ ./test14
Now things should be back to normal
$ cat test14out
This should store in the output file
along with this line.
$
15.4.3 创建输入文件描述符 #
$ cat test15
#!/bin/bash
# redirecting input file descriptors
exec 6<&0 #文件描述符6 用于保存STDIN 指向的位置
exec 0< testfile #将STDIN 重定向到一个文件
count=1 
while read line  # read 命令的所有输入都来自输入文件
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
exec 0<&6
read -p "Are you done now? " answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, this is the end.";;
esac
$ ./test15
Line #1: This is the first line.
Line #2: This is the second line.
Line #3: This is the third line.
Are you done now? y
Goodbye
$
15.4.4 创建读/写文件描述符 #

打开单个文件描述符兼做输入和输出,这样就能用同一个文件描述符对文件进行读和写两种操作

15.4.5关闭文件描述符 # 

要关闭文件描述符,只需将其重定向到特殊符号&-即可。在脚本中如下所示:
exec 3>&-

15.5 列出打开的文件描述符

bash shell 提供了lsof 命令

$ /usr/sbin/lsof -a -p $$ -d 0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 3344 rich 0u CHR 136,0 2 /dev/pts/0
bash 3344 rich 1u CHR 136,0 2 /dev/pts/0
bash 3344 rich 2u CHR 136,0 2 /dev/pts/0
$

15.6 抑制命令输出

不想显示脚本输出。将脚本作为后台进程运行时这很常见。要解决这个问题,可以将STDERR 重定向到一个名为null 文件的特殊文件。跟它的名字很像,null 文件里什么都没有。shell 输出到null 文件的任何数据都不会被保存,全部会被丢弃。

$ ls -al > /dev/null
$ cat /dev/null
$

15.7 使用临时文件

15.7.1 创建本地临时文件

在默认情况下,mktemp 会在本地目录中创建一个文件。在使用mktemp 命令时,只需指定
一个文件名模板即可。模板可以包含任意文本字符,同时在文件名末尾要加上6 个X:
$ mktemp testing.XXXXXX
 

15.7.2 在/tmp目录中创建临时文件

-t 选项会强制mktemp 命令在系统的临时目录中创建文件。在使用这个特性时,mktemp
命令会返回所创建的临时文件的完整路径名,而不只是文件名:
$ mktemp -t test.XXXXXX

15.7.3 创建临时目录

-d 选项会告诉mktemp 命令创建一个临时目录。你可以根据需要使用该目录,比如在其中
创建其他的临时文件:

$ cat test21
#!/bin/bash
# using a temporary directory 
tempdir=$(mktemp -d dir.XXXXXX)  # 创建了一个临时目录
cd $tempdir
tempfile1=$(mktemp temp.XXXXXX) # 创建了两个临时文件
tempfile2=$(mktemp temp.XXXXXX)
exec 7> $tempfile1 # 这两个临时文件又被分配给了文件描述符以用来保存脚本的输出
exec 8> $tempfile2
echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile1" >&7
echo "This is a test line of data for $tempfile2" >&8

15.8 记录消息

确实需要将输出同时送往显示器和文件。与其对输出进行两次重定向,不如改用特殊的tee 命令。
tee 命令就像是连接管道的T 型接头

$ date | tee testfile
Sun Jun 21 18:56:21 EDT 2020
$ cat testfile
Sun Jun 21 18:56:21 EDT 2020
$

第16章 脚本控制

16.1 处理信号

16.1.1 重温Linux信号

16.1.2 产生信号
1. 中断进程:Ctrl+C 组合
2. 暂停进程: Ctrl+Z 组合
16.1.3 捕获信号:trap 命令

trap 命令可以指定shell脚本需要侦测并拦截的Linux 信号。如果脚本收到了trap 命令中列出的信号,则该信号不再由shell 处理,而是由本地处理。
trap 命令的格式如下:
trap commands signals

$ cat trapsignal.sh
#!/bin/bash
#Testing signal trapping
#
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT   # 捕获信号
#
echo This is a test script.
#
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
#
echo "This is the end of test script."
exit
$

$ ./trapsignal.sh
This is a test script.
Loop #1
Loop #2
^C Sorry! I have trapped Ctrl-C
Loop #3
^C Sorry! I have trapped Ctrl-C
Loop #4
Loop #5
This is the end of test script.
$
16.1.4 捕获脚本退出

在shell 脚本中捕获信号,也可以在shell 脚本退出时捕获信号。这是在shell 完成任务时执行命令的一种简便方法。要捕获shell 脚本的退出,只需在trap 命令后加上EXIT 信号即可

$ cat trapexit.sh
#!/bin/bash
#Testing exit trapping
#
trap "echo Goodbye..." EXIT   # 捕获脚本退出
#
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
#
exit
$
$ ./trapexit.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
Goodbye...
$
16.1.5 修改或移除信号捕获

想在脚本中的不同位置进行不同的信号捕获处理,只需重新使用带有新选项的trap 命令即可

16.2 以后台模式运行脚本

使用ps -e 命令,可以看到Linux 系统中运行的多个进程

16.2.1 后台运行脚本

以后台模式运行shell 脚本非常简单,只需在脚本名后面加上&即可

$ cat backgroundscript.sh
#!/bin/bash
#Test running in the background
#
count=1
while [ $count -le 5 ]
do
sleep 1
count=$[ $count + 1 ]
done
#
exit
$
$ ./backgroundscript.sh &
[1] 2595
$
16.2.2 运行多个后台作业

在使用命令行提示符的情况下,可以同时启动多个后台作业

$ ./testAscript.sh &
[1] 2753
$ This is Test Script #1.
$ ./testBscript.sh &
[2] 2755
$ This is Test Script #2.
$ ./testCscript.sh &
[3] 2757
$ And... another Test script.
$ ./testDscript.sh &
[4] 2759
$ Then...there was one more Test script.

16.3 在非控制台下运行脚本: nohup

即便退出了终端会话,你也想在终端会话中启动shell 脚本,让脚本一直以后台模式运行到结束。这可以用nohup 命令来实现

nohup 命令的格式如下:
nohup command
下面的例子使用一个后台脚本作为command:
$ nohup ./testAscript.sh &
[1] 1828
$ nohup: ignoring input and appending output to 'nohup.out'

注意 nohup.out 文件一般在当前工作目录中创建,否则会在$HOME 目录中创建

16.4 作业控制

在作业停止后,Linux 系统会让你选择是“杀死”该作业还是重启该作业。用kill 命令可以“杀死”该作业。要重启停止的进程,则需要向其发送SIGCONT 信号。

16.4.1 查看作业

jobs 是作业控制中的关键命令,通过jobs 命令可以查看分配给shell 的作业

jobs 命令的-l 选项(小写字母l)查看作业的PID。

16.4.2 重启已停止的作业

要以后台模式重启作业,可以使用bg 命令

$ ./restartjob.sh
^Z
[1]+ Stopped ./restartjob.sh
$
$ bg
[1]+ ./restartjob.sh &
$
$ jobs
[1]+ Running ./restartjob.sh &
$

16.5 调整谦让度

在多任务操作系统(比如Linux)中,内核负责为每个运行的进程分配CPU 时间。调度优先
级[也称为谦让度(nice value)]是指内核为进程分配的CPU 时间(相对于其他进程)

调度优先级是一个整数值,取值范围从-20(最高优先级)到+19(最低优先级)。

只要记住那句俗话“好人难做。”(Nice guys finish last.)即可。越是“谦让”(nice)或是值越
大,获得CPU 的机会就越低。

16.5.1 nice命令

nice 命令允许在启动命令时设置其调度优先级。要想让命令以更低的优先级运行,只需用
nice 命令的-n 选项指定新的优先级即可:

$ nice -n 10 ./jobcontrol.sh > jobcontrol.out &

注意,nice 命令和要启动的命令必须出现在同一行中。ps 命令的输出证实,谦让度(NI列)已经调整到了10。

16.5.2 renice命令

修改系统中已运行命令的优先级。可以使用renice 命令

renice 命令对于非特权用户也有一些限制:只能对属主为自己的进程使用renice 且只能降低调度优先级。

16.6 定时运行作业

Linux 系统提供了多个在预选时间运行脚本的方法:at 命令、cron 表以及anacron。

16.6.1 使用at命令调度作业

at 命令允许指定Linux 系统何时运行脚本。

1. at 命令的格式

at 命令的基本格式非常简单:
at [-f filename] time

在使用at 命令时,该作业会被提交至作业队列。作业队列保存着通过at 命令提交的待处
理作业。针对不同优先级,有52 种作业队列。作业队列通常用小写字母a~z 和大写字母A~Z 来
指代,A 队列和a 队列是两个不同的队列。

2. 获取作业的输出

at 命令会显示分配给作业的作业号以及为作业安排的运行时间。-f 选项指明使用哪个脚本
文件。now 指示at 命令立刻执行该脚本。

3. 列出等待的作业

atq 命令可以查看系统中有哪些作业在等待

4. 删除作业

就可以用atrm 命令删除等待中的作业。指定要删除的作业号即可

$ atq
1 Thu Jun 18 16:11:00 2020 a christine
5 Fri Jun 19 16:00:00 2020 a christine
6 Fri Jun 19 16:53:00 2020 a christine
7 Thu Jun 18 20:30:00 2020 a christine
8 Thu Jun 18 17:54:00 2020 a christine
$
$ atrm 5
16.6.2 调度需要定期运行的脚本

使用cron 程序调度需要定期执行的作业。cron 在后台运行,并会检查一个特殊的表(cron 时间表),从中获知已安排执行的作业。

1. cron 时间表

cron 时间表通过一种特别的格式指定作业何时运行,其格式如下:
minutepasthour hourofday dayofmonth month dayofweek command

2. 构建cron 时间表

要列出已有的cron 时间表,可以用-l 选项:
$ crontab -l

3. 浏览cron 目录

创建的脚本对于执行时间的精确性要求不高,则用预配置的cron 脚本目录会更方便。
预配置的基础目录共有4 个:hourly、daily、monthly 和weekly

$ ls /etc/cron.*ly
/etc/cron.daily:
0anacron apt-compat cracklib-runtime logrotate [...]
apport bsdmainutils dpkg man-db [...]
4. anacron 程序

使用场景:如果某个作业在cron 时间表中设置的运行时间已到,但这时候Linux 系统处于关闭状态,那么该作业就不会运行。当再次启动系统时,cron 程序不会再去运行那些错过的作业。

anacron 判断出某个作业错过了设置的运行时间,它会尽快运行该作业

16.7 使用新shell启动脚本

每次启动新shell,bash shell 都会运行.bashrc 文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1482311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP为什么要三次握手?

TCP三次握手协议是为了在不可靠的互联网环境中可靠地建立起一个连接&#xff0c;三次握手可以确保两端的发送和接收能力都是正常的。 那么&#xff0c;为什么是三次而不是二次或四次握手呢&#xff1f; 为什么不是二次握手&#xff1f; 如果是二次握手&#xff0c;即客户端发…

带着问题阅读源码——Spring MVC是如何将url注册到RequestMappingHandlerMapping?

背景 在 Spring MVC 中&#xff0c;DispatcherServlet 是前端控制器&#xff08;front controller&#xff09;&#xff0c;它负责接收所有的 HTTP 请求并将它们映射到相应的处理器&#xff08;handler&#xff09;。为了实现这一点&#xff0c;Spring MVC 使用了适配器模式将…

设计模式-结构型模式-外观模式

外观模式&#xff08;Facade&#xff09;&#xff0c;为子系统中的一组接口提供一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。[DP] 首先&#xff0c;定义子系统的各个组件接口和具体实现类&#xff1a; // 子系统组件接…

MySQL 用了哪种默认隔离级别,实现原理是什么?

MySQL 的默认隔离级别是 RR - 可重复读&#xff0c;可以通过命令来查看 MySQL 中的默认隔离级别。 RR - 可重复读是基于多版本并发控制&#xff08;Multi-Version Concurrency Control&#xff0c;MVCC &#xff09;实现的。MVCC&#xff0c;在读取数据时通过一种类似快照的方…

if语句用法

if语句是单条件分支语句 定义&#xff1a;根据一个条件来控制程序执行流程(如图3.2)。 语法格式&#xff1a; if&#xff08;表达式&#xff09;{ 若干语句 } ★注意★&#xff1a; ① 表达式的值必须是boolean 型&#xff1b; ② 不能用0代表false&#xff1b;用1代表 true&am…

qt 5.15版本安装

1.qt5.15版本安装 2.安装慢时&#xff0c;切换到清华镜像源&#xff1a;.\qt-unified-windows-x64-online.exe --mirror https://mirrors.tuna.tsinghua.edu.cn/qt/ 3.没有qt 5.15版本在旁边进行筛选&#xff0c;只选archive

MySql外连接

目录 数据准备外连接 数据准备 -- 部门表 create table tb_dept (id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null comment 创建时间,update_time datetime…

ABB双语言共享充电宝投资理财源码/共享充电宝系统源码/共享充电宝市场分析/五级分销返利+地图显示模式

ABB双语言共享充电宝投资理财源码/五级分销返利地图显示模式/vue编译后前端 测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.3、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态laravel5&#xff0c; 源码下载&#xff1a;https://download.csdn.net/download/m0_…

2022年CSP-J认证 CCF信息学奥赛C++ 中小学初级组 第一轮真题-完善程序题解析

2022CCF认证第一轮&#xff08;CSP-J&#xff09;真题 三、完善程序题 第一题 枚举因数 从小到大打印正整数n的所有正因数。试补全枚举程序 #include <iostream> using namespace std;int main(){int n;cin >> n;vector<int> fac;fac.reserve((int)ceil(…

备战蓝桥杯---线段树基础1

引入&#xff1a;RMQ问题&#xff1a; 什么是RMQ&#xff1f; 显然&#xff0c;我们无法用前缀维护&#xff0c;因此&#xff0c;我们需要用到线段树的知识&#xff1a; 什么是线段树&#xff1f; 线段树是用一种树状结构存储一个连续区间信息的数据结构 下面我们用图解释用…

2024全国水科技大会暨高氨氮废水厌氧氨氧化处理技术论坛(四)

一、会议背景 为积极应对“十四五”期间我国生态环境治理面临的挑战&#xff0c;加快生态环境科技创新&#xff0c;构建绿色技术创新体系&#xff0c;全面落实科学技术部、生态环境部等部委编制的《“十四五”生态环境领域科技创新专项规划》&#xff0c;积极落实省校合作&…

物联网与智慧城市的融合:构建智能化、便捷化、绿色化的城市未来

一、引言 随着科技的飞速发展和城市化的不断推进&#xff0c;物联网技术正逐步渗透到城市的各个领域&#xff0c;成为推动智慧城市建设的核心力量。物联网与智慧城市的融合&#xff0c;不仅为城市治理提供了高效、智能的解决方案&#xff0c;也为市民的生活带来了前所未有的便…

Docker Swarm全解析:实现微服务高可用与故障转移的秘密武器

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Docker入门到精通》 《k8s入门到实战》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、基本概念和介绍 1、Docker Swarm 是什么&#xff0c;它与 …

APP自动化测试-入门示例

入门示例 通过上一篇博客APP自动化测试介绍-CSDN博客的学习&#xff0c;相信大家对APP自动化测试已经有了一定的了解&#xff0c;下面演示一下入门示例 1. 配置Appium 1.1. 点击Appium图标&#xff0c;打开服务器&#xff1a; 1.2. 点击Edit Configurations,进入配置页面&am…

elment-ui table表格排序后 清除排序箭头/恢复默认排序 的高亮样式

问题描述&#xff1a; 1.默认排序是按照名称升序排列&#xff08;图一&#xff09; 2.在选择了筛选项以及其他排序方式之后&#xff0c;箭头高亮是这样的&#xff08;图二&#xff09; 3.当我点击清空按钮后&#xff0c;类型清空了&#xff0c;并且传给后端的排序方式是名称/升…

文本多分类

还在用BERT做文本分类&#xff1f;分享一套基于预训练模型ERNIR3.0的文本多分类全流程实例【文本分类】_ernir 文本分类-CSDN博客 /usr/bin/python3 -m pip install --upgrade pip python3-c"import platform;print(platform.architecture()[0]);print(platform.machine…

StarRocks实战——表设计规范与监控体系

目录 前言 一、StarRocks表设计 1.1 字段类型 1.2 分区分桶 1.2.1 分区规范 1.2.2 分桶规范 1.3 主键表 1.3.1 数据有冷热特征 1.3.2 大宽表 1.4 实际案例 1.4.1 案例一&#xff1a;主键表内存优化 1.4.2 案例一&#xff1a;Update内存超了&#xff0c;导致主键表导…

【AI Agent系列】【MetaGPT多智能体学习】5. 多智能体案例拆解 - 基于MetaGPT的智能体辩论(附完整代码)

本系列文章跟随《MetaGPT多智能体课程》&#xff08;https://github.com/datawhalechina/hugging-multi-agent&#xff09;&#xff0c;深入理解并实践多智能体系统的开发。 本文为该课程的第四章&#xff08;多智能体开发&#xff09;的第三篇笔记。主要是对课程刚开始环境搭…

YOLOv9有效提点|加入SE、CBAM、ECA、SimAM等几十种注意力机制(一)

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、本文介绍 本文将以SE注意力机制为例&#xff0c;演示如何在YOLOv9种添加注意力机制&#xff01; 《Squeeze-and-Excitation Networks》 SENet提出…

【六袆 - React】Next.js:React 开发框架;Next.js开发框架的特点

Next.js&#xff1a;React 开发框架 Next.js的特点 1.直观的、基于页面的路由系统&#xff08;并支持动态路由&#xff09; Next.js 提供了基于文件系统的路由&#xff0c;意味着你可以通过创建页面文件来定义路由。 伪代码示例&#xff1a; // pages/index.js export defa…