Win*_*nix 5 bash scripts process
编辑从下面的评论中,我写了一个令人困惑/误导性的介绍,所以我正在重写它。
我有一个名为“锁屏计时器”的 bash 脚本,可以在桌面上单击它。30 分钟后,它会锁定屏幕,用户必须输入密码才能解锁屏幕。但是,如果用户改变主意,或者他们想要重置计时器,他们应该能够再次单击桌面快捷方式,并且它应该会终止之前正在运行的正在休眠和倒计时的作业。
到目前为止,我已经做了一些试验和错误,但遇到了障碍。
相关的代码片段是:
pgrep tv-timer > ~/tv-timer.log
PID=$$ # Current Process ID
Run Code Online (Sandbox Code Playgroud)
使用cat ~/tv-timer.log
:
16382
20711
Run Code Online (Sandbox Code Playgroud)
其中一个等于上面的“$PID”,但另一个是我想使用的以前运行的副本kill #####
。
找出哪个 <> "$PID" 并杀死它的最佳方法是什么?
第一次运行脚本时,只有一个条目等于“$PID”,我不想杀死它。
谢谢你的帮助!
所提出的重复(在的Sametime防止重复脚本运行)是内一个问题家长和儿童的过程。接受的答案冗长而复杂,涉及包装脚本和/或多行代码。
这里寻求的解决方案是一行新代码!
实际上,这里的被接受的答案是基于重复的op尝试,不起作用!
在跟随白兔进入不同的平行宇宙花了很多时间后,我发现以下是唯一可靠的方法:
# If called a second time, kill the first version already running
kill $(pgrep -f "${0##*/}" | grep -v ^$$)
Run Code Online (Sandbox Code Playgroud)
如果您有兴趣测试此功能,请参阅Ask UbuntuLock Screen Timer
中的代码:(在 Ubuntu 中,将在设定时间后锁定屏幕的应用程序)
该程序的相关代码片段lock-screen-timer
是这样的:
# Check if lock screen timer already running
pID=$(pgrep -f "${0##*/}") # All PIDs matching lock-screen-timer name
PREVIOUS=$(echo "$pID" | grep -v ^"$$") # Strip out this running copy ($$$)
if [ $PREVIOUS != "" ]; then
zenity --info --title="Lock screen timer already running" --text="Previous lock screen timer has been terminated."
kill "$PREVIOUS"
fi
Run Code Online (Sandbox Code Playgroud)
pgrep -f "${0##*/}"
这将查找所有出现的相同命名的运行程序 ID ${0##*/}
。虽然可执行文件被称为~/bin/lock-screen-timer
桌面快捷方式,但用于调用它。可以将其命名为“锁屏计时器”或“锁屏计时器”或“提醒我洗衣周期”。它不能像原来的问题那样被硬编码到程序中。
进程 ID 的结果列表被放入变量中$pID
echo "$pID" | grep -v ^"$$"
$pID
这将获取(所有正在运行的 的内容lock-screen-timer
,或者将其重命名为桌面快捷方式)并使用管道 ( ) 字符将进程 ID 列表通过管道传输到下一个命令|
。
下一个命令删除与当前正在运行的进程 IDgrep -v
匹配的进程ID。$$
胡萝卜 ( ^
) 告诉 grep 匹配整个单词而不是字符串。例如,当前进程 id 可能是1518
,先前版本可能是11518
、21518
或31518
。在这种情况下,只需匹配进程 id 的 4 位数字即可实现这 3 个匹配,因为1518
位于11518
. 胡萝卜与单词匹配,所以1518
<> 11518
。在进程 ID 列表中,单词由空格(在变量中)或换行符(当ps -aux
命令在屏幕上显示它们时)分隔。
这两个命令的结果是之前运行的lock-screen-timer
脚本的进程ID。进程 ID 被放入变量中$PREVIOUS
。如果没有先前的 ID,则该值将为“”(空字段)。
if [ $PREVIOUS != "" ]; then
此测试是否$PREVIOUS
不等于 ( !=
) 空/空字段""
。显然,如果我们有一个先前运行的进程 ID,我们只能杀死它!
zenity --info --title="Lock screen timer already running" ...
运行桌面快捷方式时,您无法echo
向用户发送消息,因为 GUI 不会显示它们。它们最终会出现/var/log/syslog
,你必须用cat
或gedit
等来显示它们。
zenity
是一个很好的小程序,用于显示从 bash 到(图形用户界面)(又名桌面)的对话框和表单GUI
。消息文本继续显示上一个锁屏计时器已终止。。这允许用户启动新的计时器倒计时或简单地取消。本质上,第二次调用脚本并中止是杀死已经运行的第一个脚本的方法。
kill "$PREVIOUS"
这只是杀死了我们想要执行的先前运行的版本,无论我们lock-screen-timer
是否开始新的倒计时。这与最初的问题有很大不同,因为我们将两个神秘命令的结果放入名为 的单个变量中$PREVIOUS
。