I'm using this script to build and package some applications I developed. Full content of the script is listed at the end.

It is called by this crontab entry: 50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

For debugging I copied the script to a test directory ~/test/20211101/t/ and edited it slightly. (As in removing some of the packages that are hardcoded at the end of the script.) I also manually mkdir build-dl-wwwecm and mkdir webrepos in this test directory and hg clone to get the following repos into the webrepos subdirectory:

  1. lmacros macro collection (This one is required to build any of the others. And it should be listed as the first repo to update.)

  2. lClock application

  3. KEEPHOOK utility

  4. SHUFHOOK utility

Next I added an "every minute" line to my crontab like this: * * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

The update script checks for incoming commits from the repos in the webrepos subdirectory. It then pulls the new commits and for every mak.sh script file found in the build directory tree it changes into that file's directory and runs that file. This is the full mak.sh for KEEPHOOK:

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

Now what I observe is if I call the update script myself logged in as my user (via ssh, running bash within screen, connected to the server with the ConnectBot app), then everything works as expected. The commands go like this: hg -R build-dl-wwwecm/keephook strip tip (so the update script will find a new commit to pull) then ./update-dl-wwwecm "$PWD" (to actually do the update, with the parameter for BASE specified as the test directory).

However, if the same script is called from the crontab then one thing is different: NASM appears to delete and then not create the output file keephook.com - although it does create a keephook.lst listing file that appears to be complete. No error or warning is found in the log file. All other applications are built fine.

Why is that and how to fix it?

Here's the full update script:

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

if [[ -z "$BASE" ]]
  echo "Error: No base specified." >&2
  exit 1
[[ -n "$2" ]] && BASE="$2"

[[ ! -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" ]]
    hg init "$BDIR"/"$1"
  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 ]]
      [[ ! -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
    echo === zipping "$1"
    7za a -mm=deflate -mx=9 -tzip "$TDIR"/"$1".zip *

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

1 Answer 1


Figured it out while writing the question: I wasn't redirecting the mak scripts' stderr to stdout, so the error message from NASM wasn't found in the log file created using tee. (It was found in the emails from cron and the assembler listing files, but I didn't think of checking either for error messages before. I was also under the mistaken assumption that NASM deletes the listing file on errors.)

The odd difference between running as a user and running from the crontab comes down to different NASM versions being used depending on PATH: NASM version 2.14 for crontab, NASM version 2.15.03 compiled on Dec 28 2020 for my shell session. They differ in that this lea di instruction using the word keyword is rejected by the older version but allowed by the newer one.

The fix to the update scripts is to add 2>&1 redirection to the commands that run the mak scripts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.