Linux:计划命令重启后运行一次(RunOnce等效)

我想安排一个命令在Linux机器上重新启动后运行。 我知道如何做到这一点,所以每次重新启动后用@reboot crontab项一致地运行命令,但是我只希望命令运行一次。 运行后,应该从要运行的命令队列中删除。 我基本上是在Windows世界中寻找一个相当于RunOnce的Linux。

万一重要:

 $ uname -a Linux devbox 2.6.27.19-5-default #1 SMP 2009-02-28 04:40:21 +0100 x86_64 x86_64 x86_64 GNU/Linux $ bash --version GNU bash, version 3.2.48(1)-release (x86_64-suse-linux-gnu) Copyright (C) 2007 Free Software Foundation, Inc. $ cat /etc/SuSE-release SUSE Linux Enterprise Server 11 (x86_64) VERSION = 11 PATCHLEVEL = 0 

有没有一个简单的,脚本化的方式来做到这一点?

在你的crontab中创build一个@reboot条目来运行一个名为/usr/local/bin/runonce

使用mkdir -p创build一个名为/etc/local/runonce.d/ran的目录结构。

按如下所示创build脚本/usr/local/bin/runonce

 #!/bin/sh for file in /etc/local/runonce.d/* do if [ ! -f "$file" ] then continue fi "$file" mv "$file" "/etc/local/runonce.d/ran/$file.$(date +%Y%m%dT%H%M%S)" logger -t runonce -p local3.info "$file" done 

现在,将下一次重新启动时要运行的任何脚本(仅限一次)放在目录/etc/local/runonce.dchownchmod +x 。 一旦运行,你会发现它移动到ran子目录,并附加到它的名字的date和时间。 你的syslog也会有一个条目。

我非常感谢Dennis Williamson的回答 。 我想接受它作为这个问题的答案,因为它是优雅和简单的,但是:

  • 我最终觉得需要设置太多的步骤。
  • 它需要root访问权限。

我认为他的解决scheme将成为Linux发行版的开箱即用function。

话虽如此,我写了自己的脚本来完成与丹尼斯的解决scheme差不多的事情。 它不需要任何额外的设置步骤,也不需要root访问权限。

 #!/bin/bash if [[ $# -eq 0 ]]; then echo "Schedules a command to be run after the next reboot." echo "Usage: $(basename $0) <command>" echo " $(basename $0) -p <path> <command>" echo " $(basename $0) -r <command>" else REMOVE=0 COMMAND=${!#} SCRIPTPATH=$PATH while getopts ":r:p:" optionName; do case "$optionName" in r) REMOVE=1; COMMAND=$OPTARG;; p) SCRIPTPATH=$OPTARG;; esac done SCRIPT="${HOME}/.$(basename $0)_$(echo $COMMAND | sed 's/[^a-zA-Z0-9_]/_/g')" if [[ ! -f $SCRIPT ]]; then echo "PATH=$SCRIPTPATH" >> $SCRIPT echo "cd $(pwd)" >> $SCRIPT echo "logger -t $(basename $0) -p local3.info \"COMMAND=$COMMAND ; USER=\$(whoami) ($(logname)) ; PWD=$(pwd) ; PATH=\$PATH\"" >> $SCRIPT echo "$COMMAND | logger -t $(basename $0) -p local3.info" >> $SCRIPT echo "$0 -r \"$(echo $COMMAND | sed 's/\"/\\\"/g')\"" >> $SCRIPT chmod +x $SCRIPT fi CRONTAB="${HOME}/.$(basename $0)_temp_crontab_$RANDOM" ENTRY="@reboot $SCRIPT" echo "$(crontab -l 2>/dev/null)" | grep -v "$ENTRY" | grep -v "^# DO NOT EDIT THIS FILE - edit the master and reinstall.$" | grep -v "^# ([^ ]* installed on [^)]*)$" | grep -v "^# (Cron version [^$]*\$[^$]*\$)$" > $CRONTAB if [[ $REMOVE -eq 0 ]]; then echo "$ENTRY" >> $CRONTAB fi crontab $CRONTAB rm $CRONTAB if [[ $REMOVE -ne 0 ]]; then rm $SCRIPT fi fi 

保存这个脚本(例如: runonce ), chmod +x ,然后运行:

 $ runonce foo $ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)" 

如果发生拼写错误,可以使用-r标志从runonce队列中删除命令:

 $ runonce fop $ runonce -r fop $ runonce foo 

使用sudo按照您期望的方式工作。 在下一次重新启动后仅用于启动一次服务器。

 myuser@myhost:/home/myuser$ sudo runonce foo myuser@myhost:/home/myuser$ sudo crontab -l # DO NOT EDIT THIS FILE - edit the master and reinstall. # (/root/.runonce_temp_crontab_10478 installed on Wed Jun 9 16:56:00 2010) # (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $) @reboot /root/.runonce_foo myuser@myhost:/home/myuser$ sudo cat /root/.runonce_foo PATH=/usr/sbin:/bin:/usr/bin:/sbin cd /home/myuser foo /home/myuser/bin/runonce -r "foo" 

一些说明:

  • 这个脚本复制了它被调用的环境(PATH,工作目录,用户)。
  • 它的devise基本上是推迟执行一个命令,因为它会在下一次启动序列之后立即执行。

在/etc/rc5.d中用S99设置脚本,让它在运行后自行删除。

尽pipe我注意到你不能(至less在我testing过的RHEL 5上) at @rebootat reboot ,但是你可以at now + 2 minutes ,然后shutdown -r now

这并不要求您的系统运行时间超过2分钟。

虽然我希望'runonce'命令是标准套件,但是在你想要0设置的地方也许是有用的。

我觉得这个答案是最优雅的:

将脚本放在/etc/init.d/script并用最后一行自我删除: rm $0

除非脚本是100%的失败certificate,可能明智地处理exception,以避免致命的错误循环..

我使用chkconfig让我的系统在启动后自动运行一个脚本,永远不会。 如果你的系统使用ckconfig(Fedora,RedHat,CentOs等),这将工作。

首先是脚本:

 #!/bin/bash # chkconfig: 345 99 10 # description: This script is designed to run once and then never again. # ## # Beginning of your custom one-time commands # plymouth-set-default-theme charge -R dracut -f # # End of your custom one-time commands ## ## # This script will run once # If you would like to run it again. run 'chkconfig run-once on' then reboot. # chkconfig run-once off chkconfig --del run-once 
  1. 命名脚本run-once
  2. 将脚本放在/etc/init.d/
  3. 启用脚本chkconfig run-once on
  4. 重启

系统启动时,脚本将运行一次,永远不会再运行。

也就是说,除非你想要,否则永远不会。 您始终可以使用chkconfig run-once on命令重新启用该脚本。

我喜欢这个解决scheme,因为它在系统上放置了一个且只有一个文件,并且如果需要,可以重新发出一次运行命令。

创build例如/root/runonce.sh

 #!/bin/bash #your command here sed -i '/runonce.sh/d' /etc/rc.local 

添加到/etc/rc.local

 /root/runonce.sh 

在redhat和debian系统中,你可以通过/etc/rc.local来做到这一点,它是一种autoexec.bat。