¿Por qué el ensamblador llamado desde un script no crea un archivo determinado cuando se ejecuta desde crontab?

¿Por qué el ensamblador llamado desde un script no crea un archivo determinado cuando se ejecuta desde crontab?

Estoy usandoeste guiónpara construir y empaquetar algunas aplicaciones que desarrollé. El contenido completo del guión aparece al final.

Se llama mediante esta entrada de crontab:50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

Para la depuración, copié el script en un directorio de prueba ~/test/20211101/t/y lo edité ligeramente. (Como eliminar algunos de los paquetes que están codificados al final del script). También lo hago manualmente mkdir build-dl-wwwecmy mkdir webreposen este directorio de prueba y hg cloneobtengo los siguientes repositorios en el webrepossubdirectorio:

  1. colección de macros lmacros(Este es necesario para compilar cualquiera de los demás. Y debería figurar como el primer repositorio en actualizarse).

  2. Aplicación de reloj

  3. Utilidad KEEPHOOK

  4. Utilidad SHUFHOOK

Luego agregué una línea "cada minuto" a mi crontab como esta:* * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

El script de actualización comprueba las confirmaciones entrantes de los repositorios en el subdirectorio webrepos. Luego extrae las nuevas confirmaciones y, para cada mak.sharchivo de script que se encuentra en el árbol del directorio de compilación, cambia al directorio de ese archivo y lo ejecuta. Esto esel completo mak.shpara KEEPHOOK:

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

Ahora lo que observo es que si llamo al script de actualización y he iniciado sesión como mi usuario (a través de ssh, ejecutando bash dentro de la pantalla, conectado al servidor con la aplicación ConnectBot), entonces todo funciona como se esperaba. Los comandos son así: hg -R build-dl-wwwecm/keephook strip tip(para que el script de actualización encuentre una nueva confirmación para extraer) luego ./update-dl-wwwecm "$PWD"(para realizar realmente la actualización, con el parámetro para BASE especificado como directorio de prueba).

Sin embargo, si se llama al mismo script desde crontab, entonces una cosa es diferente: NASM parece eliminar y luego no crear el archivo de salida keephook.com, aunque sí crea un keephook.lstarchivo de listado que parece estar completo. No se encuentra ningún error o advertencia en el archivo de registro. Todas las demás aplicaciones están bien construidas.

¿A qué se debe esto y cómo solucionarlo?


Aquí está el script de actualización completo:

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

Respuesta1

Lo descubrí mientras escribía la pregunta: no estaba redirigiendo el stderr de los scripts mak a la salida estándar, por lo que el mensaje de error de NASM no se encontró en el archivo de registro creado usando tee. (Se encontró en los correos electrónicos de cron y en los archivos de lista del ensamblador, pero no pensé en verificar ninguno de los mensajes de error antes. También supuse erróneamente que NASM elimina el archivo de lista en caso de errores).

La extraña diferencia entre ejecutar como usuario y ejecutar desde crontab se reduce a que se utilizan diferentes versiones de NASM dependiendo de la RUTA: NASM version 2.14para crontab, NASM version 2.15.03 compiled on Dec 28 2020para mi sesión de shell. Se diferencian en esoesta lea diinstrucciónEl uso de la wordpalabra clave es rechazado por la versión anterior pero permitido por la más nueva.

La solución a los scripts de actualización espara agregar 2>&1redireccióna los comandos que ejecutan los scripts mak.

información relacionada