我在用着这个脚本构建和打包我开发的一些应用程序。脚本的完整内容列在最后。
它由这个 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 运行之间的奇怪差异归结为根据路径使用不同的 NASM 版本:NASM version 2.14
对于 crontab,NASM version 2.15.03 compiled on Dec 28 2020
对于我的 shell 会话。他们的不同之处在于这lea di
条指令使用该word
关键字会被旧版本拒绝,但会被新版本允许。
更新脚本的修复是添加2>&1
重定向到运行 make 脚本的命令。