Почему ассемблер, вызванный из скрипта, не создает определенный файл при запуске из crontab?

Почему ассемблер, вызванный из скрипта, не создает определенный файл при запуске из crontab?

я используюэтот сценарийдля сборки и упаковки некоторых приложений, которые я разработал. Полное содержание скрипта приведено в конце.

Он вызывается этой записью в crontab:50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

Для отладки я скопировал скрипт в тестовый каталог ~/test/20211101/t/и немного его отредактировал. (Например, удалив некоторые пакеты, которые жестко закодированы в конце скрипта.) Я также вручную mkdir build-dl-wwwecmи mkdir webreposв этом тестовом каталоге и hg cloneдля того, чтобы получить следующие репозитории в webreposподкаталоге:

  1. коллекция макросов lmacros(Этот репозиторий необходим для сборки любого другого. И он должен быть указан в качестве первого репозитория для обновления.)

  2. lПриложение часов

  3. Утилита KEEPHOOK

  4. Утилита SHUFHOOK

Затем я добавил в свой crontab строку «ежеминутно» следующим образом:* * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

Скрипт обновления проверяет входящие коммиты из репозиториев в подкаталоге webrepos. Затем он извлекает новые коммиты и для каждого mak.shфайла скрипта, найденного в дереве каталога сборки, он переходит в каталог этого файла и запускает этот файл. Этополный mak.shдля KEEPHOOK:

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

Теперь я наблюдаю, что если я сам вызываю скрипт обновления, войдя в систему как мой пользователь (через ssh, запустив bash в screen, подключившись к серверу с помощью приложения ConnectBot), то все работает так, как и ожидалось. Команды выглядят так: hg -R build-dl-wwwecm/keephook strip tip(чтобы скрипт обновления нашел новый коммит для извлечения) затем ./update-dl-wwwecm "$PWD"(чтобы фактически выполнить обновление, с параметром для BASE, указанным как тестовый каталог).

Однако если тот же скрипт вызывается из crontab, то есть одно отличие: NASM, похоже, удаляет и не создает выходной файл keephook.com, хотя он создает keephook.lstфайл листинга, который выглядит полным. В файле журнала не обнаружено никаких ошибок или предупреждений. Все остальные приложения собираются нормально.

Почему это происходит и как это исправить?


Вот полный скрипт обновления:

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

решение1

Разобрался, пока писал вопрос: я не перенаправлял stderr скриптов mak в stdout, поэтому сообщение об ошибке от NASM не было найдено в файле журнала, созданном с помощью tee. (Оно было найдено в письмах от cron и в файлах листинга ассемблера, но я не подумал проверить их на наличие сообщений об ошибках раньше. Я также ошибочно предполагал, что NASM удаляет файл листинга при ошибках.)

Странное различие между запуском от имени пользователя и запуском из crontab сводится к использованию разных версий NASM в зависимости от PATH: NASM version 2.14для crontab, NASM version 2.15.03 compiled on Dec 28 2020для моей сессии shell. Они отличаются тем, чтоэта lea diинструкцияиспользование wordключевого слова отклоняется старой версией, но разрешено новой.

Исправление скриптов обновления:добавить 2>&1перенаправлениек командам, запускающим скрипты mak.

Связанный контент