スクリプトから呼び出されたアセンブラが、crontab から実行されたときに特定のファイルを作成しないのはなぜですか?

スクリプトから呼び出されたアセンブラが、crontab から実行されたときに特定のファイルを作成しないのはなぜですか?

私は使用していますこのスクリプト私が開発したいくつかのアプリケーションをビルドしてパッケージ化します。スクリプトの全内容は最後に記載されています。

これは次の crontab エントリによって呼び出されます:50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

デバッグのために、スクリプトをテスト ディレクトリにコピーし~/test/20211101/t/、少し編集しました (スクリプトの最後にハードコードされているパッケージの一部を削除するなど)。また、このテスト ディレクトリで手動でmkdir build-dl-wwwecmmkdir webreposhg 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.shKEEPHOOKのフルバージョン:

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

今私が観察しているのは、自分のユーザーとしてログインして自分で更新スクリプトを呼び出すと (ssh 経由、画面内で bash を実行、ConnectBot アプリでサーバーに接続)、すべてが期待どおりに動作するということです。コマンドは次のようになります: hg -R build-dl-wwwecm/keephook strip tip(更新スクリプトはプルする新しいコミットを見つけます)、次に./update-dl-wwwecm "$PWD"(実際に更新を実行し、BASE のパラメータをテスト ディレクトリとして指定します)。

ただし、同じスクリプトが crontab から呼び出される場合は、1 つだけ異なります。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

質問を書いているときに気付きました。mak スクリプトの stderr を stdout にリダイレクトしていなかったため、NASM からのエラー メッセージが を使用して作成されたログ ファイル内に見つかりませんでしたtee。(cron からの電子メールとアセンブラ リスト ファイル内には見つかりましたが、以前はどちらもエラー メッセージを確認することを考えていませんでした。また、NASM はエラー時にリスト ファイルを削除するという誤った想定もしていました。)

ユーザーとして実行する場合とcrontabから実行する場合の奇妙な違いは、PATHに応じて異なるNASMバージョンが使用されるためです。crontabNASM version 2.14の場合はNASM version 2.15.03 compiled on Dec 28 2020シェルセッション用です。それらは次の点で異なります。このlea di指示キーワードの使用はword古いバージョンでは拒否されますが、新しいバージョンでは許可されます。

アップデートスクリプトの修正は2>&1リダイレクトを追加するmak スクリプトを実行するコマンドに。

関連情報