
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-wwwecm
e mkdir webrepos
neste diretório de teste e hg clone
coloco os seguintes repositórios no webrepos
subdiretório:
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.)
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.sh
arquivo 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.sh
para 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.lst
arquivo 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.14
para crontab, NASM version 2.15.03 compiled on Dec 28 2020
para minha sessão de shell. Eles diferem nissoesta lea di
instruçãoo uso da word
palavra-chave é rejeitado pela versão mais antiga, mas permitido pela mais recente.
A correção para os scripts de atualização épara adicionar 2>&1
redirecionamentoaos comandos que executam os scripts mak.