Skript in einer nicht interaktiven Shell ausführen?

17

Ich habe einen Cron-Job, der ein Skript ausführt. Wenn ich das Skript über eine interaktive Shell (ssh'ed to bash) ausführe, funktioniert es einwandfrei. Wenn das Skript von selbst über cron ausgeführt wird, schlägt es fehl.

Ich vermute, dass dabei einige der Umgebungsvariablen verwendet werden, die in der interaktiven Shell festgelegt sind. Ich werde das Skript beheben und diese entfernen.

Nachdem ich Änderungen vorgenommen habe, weiß ich, dass ich das Skript in Cron in die Warteschlange stellen kann, damit es wie gewohnt ausgeführt wird. Es gibt jedoch eine Möglichkeit, das Skript von der Befehlszeile aus auszuführen. dh in einer nicht interaktiven Umgebung?

cwd
quelle
Verwandte und daher möglicherweise hilfreich: "Wie erhält man eine saubere Umgebung in einer ksh-Shell?" siehe vor allem @Gilles Antwort bezüglich unset.
Sr_
1
Über den Link von @ sr_ habe ich nachgeschlagen env, und Sie möchten es vielleicht versuchen env -i ./my-script.sh. Erhalten Sie auch eine Fehlermeldung?
Kevin
Welche Cron-Implementierung verwenden Sie?
rozcietrzewiacz
@ Kevin - Ich stimme dem zu, wenn du damit antwortest.
KWD

Antworten:

12

Die Hauptunterschiede zwischen der Ausführung eines Befehls von cron und der Ausführung in der Befehlszeile sind:

  • cron benutzt wahrscheinlich (allgemein /bin/sh) eine andere Shell ;
  • cron läuft definitiv in einer kleinen Umgebung (welche davon von der cron-Implementierung abhängt, lesen Sie die cron(8)oder crontab(5)man-Seite; im Allgemeinen gibt es nur HOMEvielleicht SHELLvielleicht LOGNAMEvielleicht USERund eine kleine PATH);
  • cron behandelt den %Charakter speziell (er wird in eine neue Zeile umgewandelt);
  • Cron-Jobs werden ohne Terminal oder grafische Umgebung ausgeführt.

Der folgende Aufruf führt das Shell-Snippet so aus, als wäre es von cron aus aufgerufen worden. Ich gehe davon aus, dass das Snippet die Zeichen 'oder nicht enthält %.

env - HOME="$HOME" USER="$USER" PATH=/usr/bin:/bin /bin/sh -c 'shell snippet' </dev/null >job.log 2>&1

Siehe auch Ausführen eines sh-Skripts vom cron aus , das zur Lösung Ihres Problems beitragen kann.

Gilles 'SO - hör auf böse zu sein'
quelle
Hi @Giles - nur an etwas gedacht - würde das Ausführen eines Skripts sudo -u user /path/to/scriptauch eine Möglichkeit sein, es ohne gesetzte Variablen auszuführen?
KWD
@cwd Nein, normalerweise nicht. sudoLöscht einige Variablen und setzt andere auf einen bekannten Wert. Dies hängt jedoch von der Konfiguration ab. Es wird häufig so konfiguriert TERM, dass beispielsweise die Gebietsschemaeinstellungen beibehalten werden .
Gilles 'SO - hör auf böse zu sein'
2

Über den Link von @ sr_ ( So erhalten Sie eine saubere Umgebung in einer ksh-Shell? ) Habe ich nach env gesucht. Vielleicht möchten Sie Folgendes versuchen:

env -i ./my-script.sh
Kevin
quelle
Das hat bei mir gut funktioniert, obwohl @Gilles Antwort auch wirklich gut ist.
KWD
@cwd: Funktioniert bei mir nicht: echo -e '#!/bin/bash -i\necho interactive $-' > ~/test.sh && chmod +x ~/test.sh && env -i ~/test.shAusgänge interactive himB.
Alix Axel
1

Ich würde vorschlagen, dass Sie absolute Pfade für Ihre Skripte verwenden, wenn Sie sie in cron einfügen und an anderer Stelle verwenden, und für alle darin verwendeten Linux-Befehle, deklarieren Sie sie besser als Variablen und verwenden Sie sie!

Gaumire
quelle
Ja. aber natürlich.
cwd
0

Cron verwendet nicht unbedingt dieselbe Shell, die Sie verwenden. prüfen:

cat /etc/crontab |grep SHELL

Um die Shell zu bestimmen und dort die Ausführung Ihres Skripts zu versuchen - funktioniert das? Dies ist eine häufige Ursache für Probleme, wenn viele Benutzer Skripts zu cron hinzufügen.

Wenn dies das Problem ist, können Sie "bash" am Anfang Ihres Skripts in cron hinzufügen, um die Ausführung dieses Skripts in bash zu erzwingen. Wenn dies das Problem nicht löst, lassen Sie es mich wissen und ich werde etwas tiefer graben.

Matt
quelle
0

Wenn Sie einige interaktive Fragen, die von einem Skript bereitgestellt werden, ignorieren möchten, können Sie Folgendes versuchen:

yes | your_command

Oder yes "n"wenn Sie nicht alle Fragen möchten.

Befehl:

yes - wiederholend positiv sein yes gibt expletiv oder standardmäßig 'y' für immer aus.

Kenorb
quelle
0

Um Ihr Skript in einer nicht interaktiven Shell auszuführen (ohne Rücksicht auf die Details von cron), können Sie dies über ausführen ssh.

Testen Sie, ob Sie wirklich in einer nicht interaktiven Shell landen:

> ssh someuser@somehost tty
not a tty

Führen Sie das Skript in einer nicht interaktiven Shell aus:

> ssh someuser@somehost /tmp/myscript.sh
dokaspar
quelle