Linux:计划命令在重启后运行一次(相当于 RunOnce)

Linux:计划命令在重启后运行一次(相当于 RunOnce)

我想安排一个命令在 Linux 机器上重启后运行。我知道如何做到这一点,所以命令每次重启后持续运行使用@rebootcrontab 条目,但我只想让命令运行一次。运行后,它应该从要运行的命令队列中删除。我本质上是在寻找一个 Linux 等效于运行一次在 Windows 世界中。

如果有关系的话:

$ 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

是否有一种简单且可编写脚本的方法来做到这一点?

答案1

在您的 crontab 中创建一个@reboot条目来运行名为 的脚本/usr/local/bin/runonce

/etc/local/runonce.d/ran创建一个名为using 的目录结构mkdir -p

创建脚本/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.dchown对其chmod +x进行适当设置。一旦运行完毕,您会发现它已移动到ran子目录中,并且日期和时间已附加到其名称中。您的 中也会有一个条目syslog

答案2

我非常感谢丹尼斯·威廉姆森的回答。我想接受它作为这个问题的答案,因为它优雅而简单,但是:

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

我认为他的解决方案作为 Linux 发行版的开箱即用功能将会非常棒。

话虽如此,我还是编写了自己的脚本,以实现与 Dennis 的解决方案大致相同的目的。它不需要任何额外的设置步骤,也不需要 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、工作目录、用户)。
  • 它的设计目的基本上是推迟命令的执行,因为它将“立即、立即”执行,直到下一次启动序列之后。

答案3

创建例如/root/runonce.sh

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

添加/etc/rc.local

/root/runonce.sh

答案4

我以前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命令重新启用该脚本。

我喜欢这个解决方案,因为它在系统上放置一个且仅一个文件,并且可以在需要时重新发出运行一次命令。

相关内容