Linux Bash 脚本编写第 5 部分 – 信号和作业

2023-10-25

在上一篇文章中,我们谈到了输入、输出和重定向在 bash 脚本中。今天我们将学习如何在Linux系统上运行和控制它们。到目前为止,我们只能从命令行界面运行脚本,但这并不是运行 Linux bash 脚本的唯一方法。

这篇文章描述了控制 Linux bash 脚本的不同方法。

 

 

Linux信号

这些是最常见的 Linux 系统信号:

Num Name Job
1 SIGHUP Process hangs up.
2 SIGINT Process Interruption.
3 SIGQUIT Proces quit or stop.
9 SIGKILL Process termination.
15 SIGTERM Process termination.
17 SIGSTOP Process stopping without termination.
18 SIGTSTP Process stopping or pausing without termination.
19 SIGCONT Process continuation after stopping.

您的 Linux bash 脚本不控制这些信号。您可以对 bash 脚本进行编程,以识别信号并根据发送的信号执行命令。

 

停止进程

要停止正在运行的进程,可以按 Ctrl+C,这会生成 SIGINT 信号来停止 shell 中当前运行的进程。


$ sleep 100  

Ctrl+C

暂停进程

Ctrl+Z 键生成 SIGTSTP 信号以停止 shell 中运行的任何进程,并将程序保留在内存中。


$ sleep 100  

Ctrl+Z

括号内的数字(1)是职位编号。

如果您尝试退出 shell,并且已为您的 shell 分配了已停止的作业,则 bash 会警告您。

您可以使用 ps 命令查看已停止的作业。


ps –l  

在 S 列(进程状态)中,它显示跟踪 (T) 或停止 (S) 状态。

如果您想终止已停止的作业,您可以杀死它的进程通过使用杀死命令.


kill processID  

 

陷阱信号

要捕获信号,您可以使用陷阱命令。如果脚本收到 trap 命令定义的信号,它将停止处理,转而由脚本处理该信号。

您可以使用 trap 命令捕获信号,如下所示:


#!/bin/bash
trap "echo 'Ctrl-C was trapped'" SIGINT
total=1
while [ $total -le 3 ]; do
	echo "#$total"
	sleep 2
	total=$(($total + 1))
done  

每次按 Ctrl+C 时,都会捕获信号并打印消息。

如果按 Ctrl+C,则会打印 trap 命令中指定的 echo 语句,而不是停止脚本。很酷,对吧?

 

捕获脚本退出

您可以使用 trap 命令捕获 shell 脚本退出,如下所示:


#!/bin/bash
# Add the EXIT signal to trap it
trap "echo Goodbye..." EXIT
total=1
while [ $total -le 3 ]; do
	echo "#$total"
	sleep 2
	total=$(($total + 1))
done  

当 bash 脚本退出时,会按预期打印 Goodbye 消息。

此外,如果您在完成工作之前退出脚本,则会触发 EXIT 陷阱。

 

修改或删除陷阱

您可以使用新选项重新发出 trap 命令,如下所示:


#!/bin/bash
trap "echo 'Ctrl-C is trapped.'" SIGINT
total=1
while [ $total -le 3 ]; do
	echo "Loop #$total"
	sleep 2
	total=$(($total + 1))
done
# Trap the SIGINT
trap "echo ' The trap changed'" SIGINT
total=1
while [ $total -le 3 ]; do
	echo "Second Loop #$total"
	sleep 1
	total=$(($total + 1))
done  

请注意更改信号陷阱后脚本如何管理信号。

你也可以移除陷阱通过使用两个破折号。


trap -- SIGNAL  

#!/bin/bash
trap "echo 'Ctrl-C is trapped.'" SIGINT
total=1
while [ $total -le 3 ]; do
	echo "#$total"
	sleep 1
	total=$(($total + 1))
done
trap -- SIGINT
echo "I just removed the trap"
total=1
while [ $total -le 3 ]; do
	echo "Loop #2 #$total"
	sleep 2
	total=$(($total + 1))
done  

请注意脚本在删除陷阱之前和删除陷阱之后如何处理信号。


$ ./myscript  

Crtl+C

第一个 Ctrl+C 被捕获,脚本继续运行,而第二个则退出脚本,因为陷阱已被删除。

 

在后台模式下运行 Linux Bash 脚本

如果您看到 ps 命令的输出,您将看到所有正在后台运行的进程,而不是绑定到终端。

我们也可以做同样的事情,只需在命令后面放置与符号(&)即可。


#!/bin/bash
total=1
while [ $total -le 3 ]; do
	sleep 2
	total=$(($total + 1))
done  

$ ./myscipt &  

完成此操作后,脚本将在系统上的单独后台进程中运行,您可以在方括号之间看到进程 ID。

当脚本终止时,您将在终端上看到一条消息。

请注意,当后台进程运行时,您可以使用终端监视器来查看 STDOUT 和 STDERR 消息,因此如果发生错误,您将看到错误消息和正常输出。

如果您退出终端会话,后台进程将退出。

那么如果关闭终端还想继续运行怎么办?

 

运行脚本而不会挂起

即使您使用以下命令退出终端会话,您也可以在后台进程中运行 Linux bash 脚本:nohup 命令.

nohup 命令阻止任何 SIGHUP 信号。当您退出终端时,它会阻止进程退出。


$ nohup ./myscript &  

运行 nohup 命令后,您看不到脚本的任何输出或错误。您将输出和错误消息发送到名为的文件nohup.out.

注意:从同一目录运行多个命令时将覆盖 nohup.out 文件内容。

 

查看职位

要查看当前作业,可以使用 jobs 命令。


#!/bin/bash
total=1
while [ $total -le 3 ]; do
	echo "#$count"
	sleep 5
	total=$(($total + 1))
done  

然后运行它。


$ ./myscript  

然后按 Ctrl+Z 停止脚本。

运行相同的 bash 脚本,但在后台使用 & 符号并将输出重定向到文件以进行澄清。


$ ./myscript > outfile &  

jobs 命令显示已停止和正在运行的作业。


jobs –l  

-l参数查看进程ID

 

重新启动停止的作业

您可以使用 bg 命令以后台模式重新启动作业。


$ ./myscript  

然后按 Ctrl+Z

现在已经停止了。


$ bg  

使用 bg 命令后,它现在以后台模式运行。

如果您有多个已停止的作业,您可以通过向 bg 命令指定作业编号来执行相同的操作。

您可以使用fg命令以前台模式重新启动作业。


$ fg 1  

 

安排工作

Linux系统提供了两种在预定义时间运行bash脚本的方法:

  • 在命令下。
  • 计划任务表。

at 命令

这是命令的格式

在 [-f 文件名] 时间

at 命令可以接受不同的时间格式:

  • 标准时间格式如 10:15。
  • AM/PM 指示器,如 11:15 PM。
  • 一个指定的时间,比如现在,午夜。

您可以使用一些不同的日期格式包含特定日期:

  • 标准日期格式,例如 MMDDYY 或 DD.MM.YY。
  • 文本日期,例如 6 月 10 日或 2 月 12 日,带或不带年份。
  • 现在+ 25 分钟。
  • 明天上午 05:15。
  • 11:15 + 7 天。

我们不想深入研究 at 命令,但现在,让它变得简单。


$ at -f ./myscript now  

如果系统有电子邮件,则可以使用 -M 参数将输出发送到电子邮件,如果没有,这将抑制 at 命令的输出。

要列出待处理的作业,请使用 atq 命令:

 

删除待处理的作业

要删除挂起的作业,请使用 atrm 命令:


$ atrm 18  

您必须为 atrm 命令指定作业编号。

 

调度脚本

如果您需要每天或每月左右的同一时间运行脚本怎么办?

您可以使用 crontab 命令来安排作业。

要列出计划的作业,请使用 -l 参数:


$ crontab –l  

crontab 的格式为:

分钟、小时、月份、月份和星期几

因此,如果您想每天 10:30 运行命令,请输入以下内容:

30 10 * * * 命令

通配符(*)用于指示 cron 将在每月的每天 10:30 执行该命令。

要在每周二下午 5:30 运行命令,您可以使用以下命令:

30 17 * * 2 命令

一周中的某一天从 0 到 6 开始,其中星期日=0,星期六=6。

要在每个月初的 10:00 运行命令:

00 10 1 ** 命令

该月的日期为 1 日至 31 日。

现在让我们保持简单,我们将在以后的文章中详细讨论 cron。

要编辑 cron 表,请使用 -e 参数,如下所示:


crontab –e  

然后键入如下命令:


 30 10 * * * /home/likegeeks/Desktop/myscript  

这将安排我们的脚本在每天 10:30 运行。

注意:有时,您会看到错误消息“资源暂时不可用”。

您所要做的就是:


$ rm -f /var/run/crond.pid  

您应该是 root 用户才能执行此操作。

就这么简单!

您可以使用预先配置的 cron 脚本目录之一,例如:

/etc/cron.每小时

/etc/cron.daily

/etc/cron.weekly

/etc/cron.monthly

只需将 bash 脚本文件放在任何一个目录中,它就会定期运行。

 

登录时启动脚本

~/.bashrc– 将您的脚本放在这里,每次您打开新终端时它都会运行。

〜/.xprofile– 当您登录到图形桌面环境(例如 GNOME 或 KDE)时,此处的脚本将由 X Window 系统运行。

/etc/X11/Xsession.d/– 如果您在 Linux 中使用 GUI 界面在启动时运行脚本,则可以使用此目录。

/etc/配置文件– 该文件包含全局环境变量以及应用于系统上所有用户的设置。

我希望您觉得这篇文章有用。继续回来。

谢谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux Bash 脚本编写第 5 部分 – 信号和作业 的相关文章

  • 没有可用的符号表信息

    我正在测试第三方的库 它崩溃了 当我想查看崩溃的原因时 我的 gdb 告诉我没有可用的调试符号 Program received signal SIGSEGV Segmentation fault Switching to Thread 0
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • GLIBCXX_3.4.26 未找到在 BeagleBone 上运行交叉编译的程序

    我有以下程序 include
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何禁用 GNOME 桌面屏幕锁定? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何阻止 GNOME 桌面在几分钟空闲时间后锁定屏幕 我已经尝试过官方手册了在红帽 https access redhat com doc
  • 如何在 shell 脚本中并行运行多个实例以提高时间效率[重复]

    这个问题在这里已经有答案了 我正在使用 shell 脚本 它读取 16000 行的输入文件 运行该脚本需要8个多小时 我需要减少它 所以我将其划分为 8 个实例并读取数据 其中我使用 for 循环迭代 8 个文件 并在其中使用 while
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • chown:不允许操作

    我有问题 我需要通过 php 脚本为系统中的不同用户设置文件所有者权限 所以我通过以下命令执行此操作 其中 1002 是系统的用户 ID file put contents filename content system chown 100
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • 如何在 Python 中计算两个日期之间的天数

    在 Python 中处理日期和时间时 计算两个日期之间的天数是一项常见任务 无论您是构建预订系统 日程安排工具还是任何其他涉及日期和时间的应用程序 计算两个日期之间的天数都是一个关键功能 在本文中 我们将讨论如何在 Python 中计算两个
  • 什么是中间人 (MITM) 攻击?

    A 中间人 MITM 攻击是一种常见的网络安全威胁 如果处理不当 可能会造成严重后果 在这种类型的攻击中 恶意行为者会拦截 中继并可能改变认为彼此直接通信的两方之间的通信 本文将深入探讨 MITM 攻击带来的威胁 攻击者使用的技术以及个人和
  • 如何利用技术进步实现完美的远程办公

    远程工作并不是一个新趋势 作家 记者和艺术家总是有机会在舒适的家中工作 尽管如此 远程办公始终与技术密切相关 在过去 远程工作人员依赖邮件服务和交通 随着这两个领域变得越来越好 越来越多的人能够在家执行工作任务 然而 直到互联网的出现 这种
  • 如何在 Debian 9 上设置 Apache 虚拟主机

    在本教程中 我们将引导您了解如何在 Debian 9 上设置 Apache 虚拟主机 Apache 虚拟主机允许您在一台计算机上托管多个域 使用虚拟主机时 您可以为每个域或子域指定不同的文档根 包含网站文件的目录 创建单独的安全策略 使用不
  • 如何在 CentOS 8 上安装 R

    R 是一种开源编程语言和免费环境 专门从事统计计算和图形表示 它由 R 统计计算基金会支持 主要供统计学家和数据挖掘人员用于开发统计软件和执行数据分析 本文介绍如何在 CentOS 8 上安装 R 先决条件 在继续本教程之前 请确保您已满足
  • 如何更改 SFTP 端口

    SFTP SSH 文件传输协议 是一种安全文件协议 用于通过加密连接在两台主机之间传输文件 它还允许您对远程文件执行各种文件操作并恢复文件传输 SFTP 可用作旧版 FTP 协议的替代品 它具有 FTP 的所有功能 但连接更安全 本文介绍如
  • 如何在 Ubuntu 18.04 上设置或更改时区

    在 Ubuntu 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 使用正确的时区对于许多与系统相关的任务和流程都很重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于相同的时区 本教程演示如
  • 如何在 Debian 9 上安装 Yarn

    Yarn 是一个与 npm 兼容的 JavaScript 包管理器 它的创建是为了解决 npm 的一系列问题 例如通过并行操作加快软件包安装过程并减少与网络连接相关的错误 在本教程中 我们将指导您如何安装Yarn在 Debian 9 系统上
  • 如何在 Ubuntu 18.04 上安装 Django

    Django 是一个免费开源的高级 Python Web 框架 旨在帮助开发人员构建安全 可扩展和可维护的 Web 应用程序 有不同的方法来安装 Django 具体取决于您的需要 它可以在系统范围内安装 也可以使用 pip 安装在 Pyth
  • 如何在 Linux 中添加目录到 PATH

    当您在命令行上键入命令时 您基本上是在告诉 shell 运行具有给定名称的可执行文件 在Linux中 这些可执行程序就像ls find file和其他文件 通常位于系统上的几个不同目录中 存储在这些目录中的任何具有可执行权限的文件都可以从任
  • 如何在 CentOS 8 上设置或更改时区

    使用正确的时区对于许多与系统相关的任务和流程至关重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于同一系统的时区 在 CentOS 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 本文介绍
  • Python range() 函数

    蟒蛇rangetype 通过定义范围的起点和终点来生成整数序列 它通常与for循环迭代数字序列 range 在 Python 2 和 3 中的工作方式有所不同 在Python 2中 有两个函数可以让你生成整数序列 range and xra
  • Linux 中的正常运行时间命令

    在本教程中 我们将介绍uptime命令 顾名思义 uptime命令显示系统已经运行了多长时间 它还显示当前时间 登录用户数以及过去 1 5 和 15 分钟的系统负载平均值 如何使用正常运行时间命令 uptime 命令的语法如下 uptime
  • 如何在 CentOS 7 上使用 VSFTPD 设置 FTP 服务器

    FTP 文件传输协议 是一种标准的客户端 服务器网络协议 允许用户在远程网络之间传输文件 有多种可用于 Linux 的开源 FTP 服务器 最流行和最广泛使用的是PureFTPd ProFTPD and vsftpd 在本教程中 我们将在
  • Python while 循环

    循环是编程语言的基本概念之一 当您想要多次重复特定的代码块直到满足给定条件时 循环会很方便 Python中有两种基本的循环结构 for and while loops 本教程涵盖了以下基础知识whilePython 中的循环 我们还将向您展
  • NumPy loadtxt 教程(从文件加载数据)

    在之前的教程中 我们讨论过NumPy 数组 我们看到了它如何使读取 解析和对数字数据执行操作的过程变得轻而易举 在本教程中 我们将讨论 NumPy loadtxt 方法 该方法用于解析文本文件中的数据并将其存储在 n 维 NumPy 数组中
  • Linux Bash 脚本编写第 3 部分 – 参数和选项

    到目前为止 您已经了解了如何编写无需用户输入即可完成工作的 Linux bash 脚本 今天我们将继续我们的 Linux bash 脚本系列 如果您想了解我们在谈论什么 我建议您查看之前的帖子 Bash 脚本基础知识 Bash 脚本 For
  • Pythonnamedtuple(将元组提升到一个新的水平)

    在本教程中 我们将深入研究命名元组 它们是什么 如何创建和操作它们 以及何时使用它们 或不使用它们 命名元组是Python内置的一部分收藏模块 并且它们提供了一种将数据捆绑在一个名称下的便捷方法 它们是 Python 内置元组数据类型的子类
  • 使用 Python 处理 CSV:综合教程

    CSV 逗号分隔值 文件是存储和共享表格数据的最常见方法之一 这些文件由行和列组成 其中每行代表一个记录 列包含由分隔符 通常是逗号 分隔的值 Python 提供了多种内置方法来处理 CSV 文件 使您可以高效地读取 写入和操作数据 本教程
  • Linux Bash 脚本编写第 5 部分 – 信号和作业

    在上一篇文章中 我们谈到了输入 输出和重定向在 bash 脚本中 今天我们将学习如何在Linux系统上运行和控制它们 到目前为止 我们只能从命令行界面运行脚本 但这并不是运行 Linux bash 脚本的唯一方法 这篇文章描述了控制 Lin