
我在用著這個腳本建立和打包我開發的一些應用程式。腳本的完整內容列在最後。
它由這個 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
子目錄中:
lmacros 巨集集合(建立任何其他庫都需要這個。並且它應該被列為第一個要更新的儲存庫。)
接下來,我在 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,使用 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 腳本的命令。