Linux: Planen Sie den Befehl so, dass er nach dem Neustart einmal ausgeführt wird (entspricht RunOnce)

Linux: Planen Sie den Befehl so, dass er nach dem Neustart einmal ausgeführt wird (entspricht RunOnce)

Ich möchte einen Befehl planen, der nach dem Neustart auf einer Linux-Box ausgeführt wird. Ich weiß, wie das geht, also der Befehlläuft konstant nach jedem Neustartmit einem @rebootCrontab-Eintrag, ich möchte jedoch, dass der Befehl nur einmal ausgeführt wird. Nachdem er ausgeführt wurde, sollte er aus der Warteschlange der auszuführenden Befehle entfernt werden. Ich suche im Wesentlichen nach einem Linux-Äquivalent zuRenn einmalin der Windows-Welt.

Falls es wichtig ist:

$ 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

Gibt es hierfür eine einfache Möglichkeit per Skript?

Antwort1

Erstellen Sie einen @rebootEintrag in Ihrer Crontab, um ein Skript namens auszuführen /usr/local/bin/runonce.

Erstellen Sie eine Verzeichnisstruktur mit dem Namen /etc/local/runonce.d/ranusing mkdir -p.

Erstellen Sie das Skript /usr/local/bin/runoncewie folgt:

#!/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

Platzieren Sie nun alle Skripts, die Sie beim nächsten Neustart ausführen möchten (nur einmal), im Verzeichnis /etc/local/runonce.dund chownführen Sie chmod +xsie entsprechend aus. Sobald es ausgeführt wurde, wird es in das ranUnterverzeichnis verschoben und das Datum und die Uhrzeit werden an seinen Namen angehängt. Es wird auch einen Eintrag in Ihrem geben syslog.

Antwort2

Ich schätze die Mühe wirklich sehr,Dennis Williamsons Antwort. Ich wollte es als Antwort auf diese Frage akzeptieren, da es elegant und einfach ist, aber:

  • Letztendlich hatte ich das Gefühl, dass für die Einrichtung zu viele Schritte erforderlich waren.
  • Es erfordert Root-Zugriff.

Ich denke, seine Lösung wäre als Out-of-the-Box-Funktion einer Linux-Distribution großartig.

Allerdings habe ich mein eigenes Skript geschrieben, um mehr oder weniger dasselbe zu erreichen wie Dennis' Lösung. Es erfordert keine zusätzlichen Einrichtungsschritte und keinen Root-Zugriff.

#!/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

Speichern Sie dieses Skript (z. B.: runonce), chmod +xund führen Sie es aus:

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

Im Falle eines Tippfehlers können Sie einen Befehl mit dem Flag -r aus der Runonce-Warteschlange entfernen:

$ runonce fop
$ runonce -r fop
$ runonce foo

Die Verwendung von sudo funktioniert wie erwartet. Nützlich, um einen Server nach dem nächsten Neustart nur einmal zu starten.

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"

Einige Notizen:

  • Dieses Skript repliziert die Umgebung (Pfad, Arbeitsverzeichnis, Benutzer), in der es aufgerufen wurde.
  • Es ist grundsätzlich so konzipiert, dass die Ausführung eines Befehls, als würde er „genau hier und jetzt“ ausgeführt, bis nach der nächsten Startreihenfolge verschoben wird.

Antwort3

Erstellen Sie beispielsweise /root/runonce.sh:

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

Hinzufügen zu /etc/rc.local:

/root/runonce.sh

Antwort4

Früher ließ ich chkconfigmein System nach dem Booten einmal automatisch ein Skript ausführen und danach nie wieder. Wenn Ihr System ckconfig verwendet (Fedora, RedHat, CentOs usw.), funktioniert dies.

Zuerst das Skript:

#!/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. Benennen Sie das Skriptrun-once
  2. Platzieren Sie das Skript in/etc/init.d/
  3. Aktivieren des Skriptschkconfig run-once on
  4. Neustart

Beim Systemstart wird Ihr Skript einmal ausgeführt und nie wieder.

Das heißt, nie wieder, es sei denn, Sie möchten es. Sie können das Skript jederzeit mit dem Befehl wieder aktivieren chkconfig run-once on.

Mir gefällt diese Lösung, weil sie nur eine einzige Datei auf dem System ablegt und weil der einmal ausgeführte Befehl bei Bedarf erneut ausgeführt werden kann.

verwandte Informationen