草庐IT

linux - 用于启动进程的 Bash 脚本,随机等待,终止进程,重新启动

coder 2023-06-18 原文

我是一个绝对的初学者,我正在尝试创建一个 bash 脚本来随机化命令行应用程序的启动和退出。我计划在 autostart.sh 中稍作延迟后在启动时自动启动脚本 (Crunchbang)(在此处找到:http://interwebworld.co.uk/2011/10/23/how-to-launch-programs-automatically-at-startup-in-crunchbang-linux/)

(sleep 300s && /home/myuser/Scripts/randomizer.sh) &

这基本上是我需要在 randomizer.sh 脚本中用一些伪代码完成的:

start applicationfile
wait a random period of time
if applicationfile is still running
    kill its process
    wait a random period of time
    exit this script and restart this script
else exit this script and restart this script

我目前拥有的 randomizer.sh 如下(包含伪代码的残余部分), sleep 延迟在此处找到:http://blog.buberel.org/2010/07/howto-random-sleep-duration-in-bash.html,欢迎提供帮助。

/path/to/applicationfile -s 111.222.333.444 -u username -p password
sleep $[ ( $RANDOM % 150 ) + 60 ]m
if applicationfile is still running
    kill $(ps aux | grep '[u]sername' | awk '{print $2}')
    sleep $[ ( $RANDOM % 150 ) + 60 ]m
    exec $randomizer.sh
else exec $randomizer.sh

我“认为”非伪部分应该可以正常工作,但如果我错了请纠正我或进行调整。初始的 applicationfile 命令行按原样工作,我已经测试了进程终止行并且它按预期工作。 Applicationfile 没有从命令行结束自身的内置方法,但是远程机器上的死连接将在本地被杀死 5 分钟后被杀死,所以在本地杀死它可以满足我的需要。

我不知道如何处理 kill 上面的那一行,它首先检查进程“是否”正在运行。抱歉文字墙,但我想表明我已经尽我所能。

最佳答案

在 bash 中,$! 是最后启动的进程的 PID,所以按照这样的模式应该可以工作:

mycommand &
last_pid=$!
sleep( $RANDOM )
kill -KILL $last_pid

当然,您可以随意更改发送的信号、$RANDOM 与您想 sleep 的时间之间的关系等。

新进程不太可能获得相同的 PID,除非 a) 休眠时间很长或 b) 您的机器启动了很多短暂的进程。在 Linux 上,PID 是循环分配的,最大值为 32,765,因此,粗略地说,您必须在 sleep 时间内启动大约那么多的进程,才能冒着遇到属于不同进程的相同 PID 的风险。如果这是一个风险,您可以添加一个测试(从技术上讲,这里有一场比赛,但不太可能成为问题)。以下内容似乎可以满足您的要求。

signal=KILL

sleep_a_while () {
    sleep $[ ( $RANDOM % 150 ) + 60 ]m
}

while true; do
    # Note: command launched in background:
    /path/to/applicationfile -s 111.222.333.444 -u username -p password &

    # Save PID of command just launched:
    last_pid=$!

    # Sleep for a while:
    sleep_a_while

    # See if the command is still running, and kill it and sleep more if it is:
    if ps -p $last_pid -o comm= | grep -qs '^applicationfile$'; then
        kill -$signal $last_pid 2> /dev/null
        sleep_a_while
    fi

    # Go back to the beginning and launch the command again
done

我用等效循环替换了 self-exec

kill 行,由于竞争,将 stderr 重定向到 /dev/null 是可取的。该进程可能会在 ps 完成和执行 kill 之间自然退出,从而产生无害的错误消息。这种竞争是不可避免的(也是无害的),除非 PID 存在的测试和信号的发送是重合的。

如果打算同时运行最多一个 applicationfile 实例,则可以通过替换来完全避免这种竞争:

# See if the command is still running, and kill it and sleep more if it is:
if ps -p $last_pid -o comm= | grep -qs '^applicationfile$'; then
    kill -$signal $last_pid 2> /dev/null
    sleep_a_while
fi

与:

killall -q applicationfile && sleep_a_while

如果这不能使用,Keith Reynolds 的测试变体更好,因为它避免了不必要的 grep,即使用:

# See if the command is still running, and kill it and sleep more if it is:
if [ "$(ps -p $last_pid -o comm=)" = "applicationfile" ]; then
    kill -$signal $last_pid 2> /dev/null
    sleep_a_while
fi

关于linux - 用于启动进程的 Bash 脚本,随机等待,终止进程,重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22867130/

有关linux - 用于启动进程的 Bash 脚本,随机等待,终止进程,重新启动的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  5. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  6. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  7. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  8. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  9. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  10. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

随机推荐