為什麼從腳本呼叫的彙編程式在從 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 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.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 呼叫相同的腳本,則有一件事會有所不同: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,因此在使用tee. (它是在 cron 和彙編程式清單檔案的電子郵件中找到的,但我之前沒有想到檢查其中任何一個是否有錯誤訊息。我還錯誤地認為 NASM 會在出現錯誤時刪除清單檔案。)

以使用者身分執行和從 crontab 運行之間的奇怪差異歸結為根據 PATH 使用不同的 NASM 版本:NASM version 2.14對於 crontab,NASM version 2.15.03 compiled on Dec 28 2020對於我的 shell 會話。他們的不同之處在於lea di條指令使用該word關鍵字會被舊版拒絕,但會被新版本允許。

更新腳本的修復是新增2>&1重定向到執行 make 腳本的命令。

相關內容