Warum erstellt der vom Skript aufgerufene Assembler eine bestimmte Datei nicht, wenn er von Crontab ausgeführt wird?

Warum erstellt der vom Skript aufgerufene Assembler eine bestimmte Datei nicht, wenn er von Crontab ausgeführt wird?

Ich benutzedieses Skriptum einige von mir entwickelte Anwendungen zu erstellen und zu verpacken. Der vollständige Inhalt des Skripts ist am Ende aufgeführt.

Es wird durch diesen Crontab-Eintrag aufgerufen:50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

Zum Debuggen habe ich das Skript in ein Testverzeichnis kopiert ~/test/20211101/t/und leicht bearbeitet. (Ich habe beispielsweise einige der Pakete entfernt, die am Ende des Skripts fest codiert sind.) Ich habe auch manuell mkdir build-dl-wwwecmund mkdir webreposin diesem Testverzeichnis hg clonedie folgenden Repos in das webreposUnterverzeichnis geladen:

  1. lmacros Makro-Sammlung(Dieses ist zum Erstellen aller anderen erforderlich. Und es sollte als erstes zu aktualisierendes Repo aufgeführt werden.)

  2. lClock-Anwendung

  3. KEEPHOOK-Dienstprogramm

  4. SHUFHOOK-Dienstprogramm

Als nächstes habe ich meiner Crontab eine „jede Minute“-Zeile wie folgt hinzugefügt:* * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

Das Update-Skript prüft, ob eingehende Commits aus den Repos im Unterverzeichnis webrepos eingehen. Anschließend zieht es die neuen Commits und mak.shwechselt für jede im Build-Verzeichnisbaum gefundene Skriptdatei in das Verzeichnis dieser Datei und führt diese Datei aus. Dies istdie volle Länge mak.shfür KEEPHOOK:

#! /bin/bash
nasm -I ../lmacros/ -f bin transien.asm -l keephook.lst -o keephook.com "$@"

Was ich jetzt beobachte, ist, dass alles wie erwartet funktioniert, wenn ich das Update-Skript selbst aufrufe, während ich als mein Benutzer angemeldet bin (über SSH, indem ich Bash auf dem Bildschirm ausführe und über die ConnectBot-App mit dem Server verbunden bin). Die Befehle lauten wie folgt: hg -R build-dl-wwwecm/keephook strip tip(damit das Update-Skript ein neues Commit zum Abrufen findet) dann ./update-dl-wwwecm "$PWD"(um das Update tatsächlich durchzuführen, wobei der Parameter für BASE als Testverzeichnis angegeben ist).

Wenn das gleiche Skript jedoch von der Crontab aufgerufen wird, ist etwas anders: NASM scheint die Ausgabedatei zu löschen und dann nicht zu erstellen keephook.com- obwohl es eine Listendatei erstellt keephook.lst, die vollständig zu sein scheint. In der Protokolldatei sind weder Fehler noch Warnungen zu finden. Alle anderen Anwendungen werden problemlos erstellt.

Warum ist das so und wie kann das Problem behoben werden?


Hier ist das vollständige Update-Skript:

#! /bin/bash

# Usage of the works is permitted provided that this
# instrument is retained with the works, so that any entity
# that uses the works is notified of this instrument.
#
# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

BASE="$1"
if [[ -z "$BASE" ]]
then
  echo "Error: No base specified." >&2
  exit 1
fi
SDIR="$BASE"/webrepos
[[ -n "$2" ]] && BASE="$2"
BDIR="$BASE"/build-dl-wwwecm
TDIR="$BASE"/wwwecm/download
ODIR="$BASE"/wwwecm/download/old

[[ ! -d "$BDIR" ]] && mkdir -p "$BDIR"
[[ ! -d "$TDIR" ]] && mkdir -p "$TDIR"
[[ ! -d "$ODIR" ]] && mkdir -p "$ODIR"

function update() {
    # $1 = path below BDIR
    # $2 = "-r" if there is a branch
    # $3 = branch name if there is a branch
  if [[ ! -d "$BDIR"/"$1" ]]
  then
    hg init "$BDIR"/"$1"
  fi
  cd "$BDIR"/"$1"
  if var="$(hg incoming "$SDIR"/"$1" $2 $3)"; then
    echo "$var"
    hg pull "$SDIR"/"$1" $2 $3 && hg up $3
    find . -name mak.sh -print0 | \
      ONE="$1" xargs -r0 bash -c \
        'for file; do echo === "$ONE"/"$file"; (cd "${file%/*}"; "./${file##*/}"); done' scriptlet
    if [[ -f "$TDIR"/"$1".zip ]]
    then
      [[ ! -d "$ODIR"/"$1" ]] && mkdir -p "$ODIR"/"$1"
      datestamp="$(date -r "$TDIR"/"$1".zip +%Y%m%d)"
      echo === mv --backup=numbered "$TDIR"/"$1".zip "$ODIR"/"$1"/"$datestamp".zip
      mv --backup=numbered "$TDIR"/"$1".zip "$ODIR"/"$1"/"$datestamp".zip
    fi
    echo === zipping "$1"
    7za a -mm=deflate -mx=9 -tzip "$TDIR"/"$1".zip *
  fi
}

update lmacros
update keephook
update shufhook
update rxansi
update lclock
update seekext
update tsr
update fdapm
update renumber
touch "$BDIR"/lastrun

Antwort1

Habe es beim Schreiben der Frage herausgefunden: Ich habe die stderr-Ausgabe der Mak-Skripte nicht auf stdout umgeleitet, daher wurde die Fehlermeldung von NASM nicht in der mit erstellten Protokolldatei gefunden tee. (Sie wurde in den E-Mails von Cron und den Assembler-Listing-Dateien gefunden, aber ich habe vorher nicht daran gedacht, in beiden nach Fehlermeldungen zu suchen. Ich war auch der falschen Annahme, dass NASM die Listing-Datei bei Fehlern löscht.)

Der seltsame Unterschied zwischen der Ausführung als Benutzer und der Ausführung aus der Crontab resultiert aus den verschiedenen NASM-Versionen, die je nach PATH verwendet werden: NASM version 2.14für die Crontab, NASM version 2.15.03 compiled on Dec 28 2020für meine Shell-Sitzung. Sie unterscheiden sich darin, dassdiese lea diAnweisungDie Verwendung des wordSchlüsselworts wird von der älteren Version abgelehnt, von der neueren jedoch zugelassen.

Der Fix für die Update-Skripte ist2>&1Umleitung hinzufügenzu den Befehlen, die die Mak-Skripte ausführen.

verwandte Informationen