Por que o assembler chamado a partir do script não cria um determinado arquivo quando executado no crontab?

Por que o assembler chamado a partir do script não cria um determinado arquivo quando executado no crontab?

estou a usareste roteiropara construir e empacotar alguns aplicativos que desenvolvi. O conteúdo completo do script está listado no final.

É chamado por esta entrada do crontab:50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

Para depuração, copiei o script para um diretório de teste ~/test/20211101/t/e editei-o ligeiramente. (Como na remoção de alguns dos pacotes que estão codificados no final do script.) Também faço manualmente mkdir build-dl-wwwecme mkdir webreposneste diretório de teste e hg clonecoloco os seguintes repositórios no webrepossubdiretório:

  1. coleção de macros lmacros(Este é necessário para construir qualquer um dos outros. E deve ser listado como o primeiro repositório a ser atualizado.)

  2. Aplicativo lClock

  3. Utilitário KEEPHOOK

  4. Utilitário SHUFHOOK

Em seguida, adicionei uma linha “a cada minuto” ao meu crontab assim:* * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

O script de atualização verifica os commits recebidos dos repositórios no subdiretório webrepos. Em seguida, ele extrai os novos commits e, para cada mak.sharquivo de script encontrado na árvore de diretórios de construção, ele muda para o diretório desse arquivo e o executa. Isso éo completo mak.shpara KEEPHOOK:

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

Agora o que observo é que se eu mesmo chamar o script de atualização logado como meu usuário (via ssh, executando o bash na tela, conectado ao servidor com o aplicativo ConnectBot), tudo funcionará conforme o esperado. Os comandos são assim: hg -R build-dl-wwwecm/keephook strip tip(para que o script de atualização encontre um novo commit para extrair) e então ./update-dl-wwwecm "$PWD"(para realmente fazer a atualização, com o parâmetro para BASE especificado como o diretório de teste).

No entanto, se o mesmo script for chamado a partir do crontab, uma coisa será diferente: o NASM parece excluir e não criar o arquivo de saída keephook.com- embora crie um keephook.lstarquivo de listagem que parece estar completo. Nenhum erro ou aviso foi encontrado no arquivo de log. Todos os outros aplicativos são bem construídos.

Por que isso acontece e como consertar?


Aqui está o script de atualização 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

Responder1

Descobri isso enquanto escrevia a pergunta: eu não estava redirecionando o stderr dos scripts mak para stdout, então a mensagem de erro do NASM não foi encontrada no arquivo de log criado usando tee. (Ele foi encontrado nos e-mails do cron e nos arquivos de listagem do assembler, mas eu não pensei em verificar mensagens de erro antes. Eu também estava sob a suposição equivocada de que o NASM exclui o arquivo de listagem em caso de erros.)

A estranha diferença entre executar como usuário e executar a partir do crontab se resume às diferentes versões do NASM usadas dependendo do PATH: NASM version 2.14para crontab, NASM version 2.15.03 compiled on Dec 28 2020para minha sessão de shell. Eles diferem nissoesta lea diinstruçãoo uso da wordpalavra-chave é rejeitado pela versão mais antiga, mas permitido pela mais recente.

A correção para os scripts de atualização épara adicionar 2>&1redirecionamentoaos comandos que executam os scripts mak.

informação relacionada