Pourquoi avons-nous besoin de la commande «at» sous Linux?

38

J'étudiais le code dans lequel la atcommande est utilisée. J'ai regardé autour de moi et j'ai constaté qu'il est utilisé pour exécuter des travaux par lots. Il est utilisé pour planifier des travaux. Il reçoit en entrée une commande et une heure, relative ou absolue.

Donc, ma première question est: pourquoi la atcommande est-elle utilisée? Dans quelles circonstances faut-il utiliser at? Je l’ai rencontré lorsqu’un code de script bash essayait de désinstaller un logiciel et que certains services d’arrière-plan devaient être redémarrés.

Ma deuxième question: quelle est la différence entre une commande exécutée en tant que travail par lots et une commande exécutée directement dans une commande appelante (ou dans un sous-shell)?

Akshay Patil
la source

Réponses:

47

La réponse de Bernhard est correcte: dans les systèmes multi-utilisateurs, la possibilité d'exécuter des programmes lourds à des heures impies de la nuit est particulièrement pratique, à la fois pour la personne qui soumet le travail et ses collègues. Cela fait partie de "jouer gentil".

J'ai fait l'essentiel de mon doctorat Les calculs de cette façon, combinant le script avec la commande nice qui rétrogradait la priorité de mon travail lorsque d’autres personnes tenaient la machine occupée, tout en laissant intacte sa capacité à exploiter toutes les ressources système la nuit.

J'ai utilisé la même commande pour vérifier si mon programme était en cours d'exécution et le redémarrer si nécessaire.

De plus, vous devez garder à l’esprit que at était écrit bien avant screen, tmux , etc., de sorte que c’était un moyen simple d’avoir un shell séparé, c’est-à-dire qui ne mourrait pas une fois que vous êtes déconnecté du système.

Enfin, vous devriez également remarquer que c’est différent de cron, qui existe aussi depuis longtemps. Les mensonges de différence dans le fait que , à est occasionnelle, tandis que Cron, étant si répétitif, est plus adapté pour les emplois système qui a vraiment besoin d' être exécuté pour toujours à intervalles fixes: en effet, à vous donne votre propre environnement, avec vos propres paramètres ( et choix) de la variable d'environnement, alors que cron utilise un ensemble minimal de variables d'environnement (il suffit de vérifier la différence dans PATH , à titre d'exemple).

MariusMatutiae
la source
15
Une autre différence avec cron est également intéressante: elle atconserve votre environnement tel qu'il était lors de la planification du travail: même répertoire de travail, variables d'environnement, ...
Carlos Campderrós
10
Il y a aussi batch, qui est presque identique à at, mais attendra une charge faible à la place, et apparemment, at -q zle travail sera agréable en lui-même, alors at -q Zqu'il attendra l'heure, puis attendra que la charge tombe, et le travail aussi. Wow, quelle charge de fonctionnalités rarement utilisées!
Ulrich Schwarz
16

J'utilise cette atcommande lorsque je dois effectuer des traitements lourds sur des données, que je souhaite faire exécuter pendant la nuit, lorsque je ne suis pas derrière mon ordinateur. Bien sûr, je pourrais commencer le processus juste après mon départ, mais c'est quelque chose que j'ai tendance à oublier.

Le résultat de la commande n'est pas différent de l'exécution régulière du script ou de la commande.

Bernhard
la source
15

Lorsque vous avez des questions de ce type, consultez toujours les pages de manuel. Ils peuvent être très instructifs.

Ce qu'il fait

extrait de la page de manuel

NAME
       at, batch, atq, atrm - queue, examine or delete jobs for later execution

DESCRIPTION
       at  and  batch  read  commands  from  standard  input or a specified file
       which are to be executed at a later time, using /bin/sh.

Usage

L'utilisation des outils:

Usage: at [-V] [-q x] [-f file] [-mldbv] timespec ...
       at [-V] [-q x] [-f file] [-mldbv] -t time
       at -c job ...
       atq [-V] [-q x]
       atrm [-V] job ...
       batch

atcomprend 4 commandes ( at, atq, atrm, et batch). Vous utilisez atet batchpour planifier les travaux, atqpour voir ce qui est planifié et atrmpour supprimer un travail avant son exécution.

$ at -f <cmd> timspec

Timespec

Le temps d'exécution du attravail peut être spécifié de différentes manières.

extrait de la page de manuel

At autorise des spécifications de temps assez complexes, étendant la norme POSIX.2. Il accepte les heures de la forme HH: MM pour exécuter un travail à une heure précise de la journée. (Si cette heure est déjà passée, le lendemain est supposé.) Vous pouvez également spécifier minuit, midi ou l'heure du thé (16h) et vous pouvez avoir une heure suffixée avec AM ou PM pour courir le matin. ou le soir. Vous pouvez également indiquer le jour où le travail sera exécuté, en indiquant une date sous la forme mois-nom jour avec une année optionnelle ou une date sous la forme MMJJ [CC] AA, MM / JJ / [CC] AA. JJ.MM. [CC] AA ou [CC] AA-MM-JJ. La spécification d'une date doit suivre la spécification de l'heure. Vous pouvez également donner des heures comme maintenant + compter les unités de temps, où les unités de temps peuvent être des minutes, des heures, des jours,

Exemples

Disons que vous avez ce script shell.

$ cat mycrontest.sh

#!/bin/bash
 echo "It is now $(date +%T) on $(date +%A)"

Échantillon échantillon:

$ ./mycrontest.sh
It is now 18:37:42 on Friday

Échantillon aux offres d'emploi:

$ at -f mycrontest.sh  10pm tomorrow
job 14 at Sun Jul  8 22:00:00 2007

$ at -f mycrontest.sh 2:00 tuesday
job 15 at Tue Jul 10 02:00:00 2007

$ at -f mycrontest.sh 2:00 july 11
job 16 at Wed Jul 11 02:00:00 2007

$ at -f mycrontest.sh 2:00 next week
job 17 at Sat Jul 14 02:00:00 2007

Les références

slm
la source
Il semble qu'une version très différente de celle atdisponible sur mon installation Cygwin soit disponible: elle ne semble pas être liée à batch, aucune option courte n'est prise en charge, il n'y a pas d'option silencieuse et aucune page manni aucune infopage ne sont incluses.
Hashim
@Hashim - cygwin est sa propre bête.
slm
6

Vous pouvez exécuter des travaux par lots sous UNIX / Linux à l'aide de l'une des trois commandes - at, batch ou cron.

Planifiez un travail en utilisant une date et une heure spécifiques

Syntax:

    $ at time date
For example, to schedule a job at 11 am on May 20, use the following at command.

    $ at 11 am may 20
Roshan Bagdiya
la source
Oui, j'ai cette compréhension de "at" et de son utilisation. D'autres personnes ont répondu de manière plus pertinente.
Akshay Patil
5

Votre administrateur réseau vous informe que vos serveurs Web seront soumis à une maintenance commençant à 19 heures et se terminant à 2 heures. Vous voulez envoyer une notification de maintenance à l'avance et vous voulez une disponibilité maximale de votre système. Allez-vous rester éveillé toute la nuit, prêt à exécuter diverses commandes, puis le redémarrer plus tard? Non, vous voudriez utiliser atpour planifier ces tâches, puis aller au lit / jouer aux skyrim et oublier.

Arrête de blesser Monica
la source
1

atpeut également être un moyen très pratique de déclencher des rappels. Ma machine de développement actuelle fonctionne sous OSX, donc atla simple méthode notify.bashque je bricole peut être vraiment utile:

$ at 5pm
notify.bash -t 'Work is over' -m "Don't forget to rollback INT environment"
^D
$ at now + 15 minutes
notify.bash -m 'Check tests' -l 'http://integration.example.com/jobs/XXXX'
^D
$ at now + 10 minutes
notify.bash -m 'Check the fridge, pudding should be done!'
^D

notify.bash

#!/bin/bash

DEFAULT_TITLE='Hey! Listen!'
TITLE="$DEFAULT_TITLE"
LINK=
MESSAGE=

function args.help () {
    local error="$1"
    if [ "$error" ]; then
        echo >&2 "$error"
    fi
    cat >&2 <<EOF
Usage $0 <options>

Displays a message using an Applescript notification box

Options
-------

--title <text>    Sets the title, otherwise the default is used ("$DEFAULT_TITLE")
 -t     <text>    Alias for --title

--link  <url>     Add a button to open a link
 -l     <url>     Alias for --link

--body  <text>    Set the message body
 -m     <text>    Alias for --body
EOF
}

function args.verify-not-empty () {
    local value="$1"
    local varname="$2"

    if [ "$value" ]; then
        echo "$value"
    elif [ "$varname" ]; then
        args.help "$varname cannot handle an empty argument"
        exit 1
    else
        args.help \
            "The programmer forgot to include context, something was empty which shouldn't have been, but I can't tell you much more than that. Sorry :("
        exit 1
    fi
}

function args.parse () {
    while [ "$1" ]
    do
        case "$1" in
            '-t' | '--title')
                shift
                TITLE=$(args.verify-not-empty "$1" title)
                shift
                ;;
            '-l' | '--link')
                shift
                LINK=$(args.verify-not-empty "$1" link)
                shift
                ;;
            '-m' | '--body')
                shift
                if [[ "$1" = '-' ]]; then
                    MESSAGE=$(cat -)
                else
                    MESSAGE="$1"
                fi
                MESSAGE=$(args.verify-not-empty "$MESSAGE" body)
                shift
                ;;
            *)
                args.help "Unrecognized argument: $1"
                exit 1
        esac
    done
    if [[ ! "$MESSAGE" ]]; then
        args.help "Message body was not specified"
        exit 1
    fi
}

function message.display-no-link () {
    osascript > /dev/null <<EOF
tell application "Finder"
  activate
  display alert "$TITLE" ¬
          message "$MESSAGE" ¬
          buttons { "Acknowledge" } ¬
          default button "Acknowledge"
end tell
return
EOF
}

function message.display-with-link () {
    osascript > /dev/null <<EOF
tell application "Finder"
  activate
  display alert "$TITLE" ¬
          message "$MESSAGE\n\nClick 'Open Link' to go to $LINK" ¬
          buttons { "Acknowledge", "Open Link" } ¬
          default button "Open Link"
          set response to button returned of the result
          if response is "Open Link" then open location "$LINK"
end tell
return
EOF
}

function message.display () {
    if [ "$LINK" ]; then
        message.display-with-link
    else
        message.display-no-link
    fi
}

args.parse "$@"
message.display
Morgen
la source