我写了一个大脚本来运行一系列测试。每个测试都是一个独立的功能,我将这些功能串行调用以完成工作。
我现在想要从中断的最后一个函数中恢复脚本运行(例如,在系统挂起的情况下)。我现在使用的逻辑是将进度状态写入文件,然后检查文件内容以确定从何处启动脚本并从那里继续。
但是,我无法继续使用此逻辑,因为我想在脚本中引入一个菜单,我希望能够从中选择:
1)从头到尾运行所有测试
2)运行单独测试(带有单独测试选项的另一个菜单)
3)从上次中止恢复
我已经编写了菜单代码,但仍然没有弄清楚如何使用菜单系统中使用的case构造来适应我现有的逻辑。我对目前正在使用的最后一次中止逻辑的当前简历感到不满,这是:
fn1()
{
#do a bunch of things
echo 1 > progress.log
fn2
}
fn2()
{
STATUS=`cat progress.log`
case "$STATUS" in
1)
#do a bunch of things
echo 2 > progress.log
fn3
;;
*)
fn3
;;
esac
}
..
..
# and more functions in the same style as fn2
..
# main call
if [ -f progress.log ]
fn2
else
fn1
fi
任何更简洁的方法都可以恢复逻辑,同时将其与在需要时单独运行测试的能力相结合?感谢。
答案 0 :(得分:2)
这样的事情怎么样?删除将它们链接在一起的fn1..N中的逻辑,但仍然在其中写入progress.log
文件,然后执行以下操作:
runtest()
{
# run test X where X is 1..N
case "$1" in
1) fn1 ;;
2) fn2 ;;
3) fn3 ;;
*) echo "Invalid test number $1" ;;
esac
}
runtests()
{
START="$1"; shift
[ -z "$START"] && START=1 # default to test 1
for i in $(seq "$START" 50); do # replace 50 with max test number
runtest $i
done
}
# from your menu, run from start:
runtests 1
# from menu, run from progress
runtests $(< progress.log)
# from menu, run test TESTNUM
runtest $TESTNUM
# or by name (this is dangerous if you don't trust the user):
eval "$TESTNAME"
编辑:使用此版本,您可以使用测试名称替换fn1,fn2等,这样您仍然可以使用一个最常用的N接口来将它们组合在一起。
答案 1 :(得分:1)
Bash支持“案例级联”,也就是说。因此,您可以通过案例级联来写入/读取文件中的进度和相应的行为。例如
function write_progress
{
local step_name=$1
echo "$(date '+%F %H:%M:%S') $step_name" >> "$PROGRESS_FILE"
if [ $? -ne 0 ]; then
error_out "failed to update progress"
fi
}
function read_proress
{
local step_name
step_name=$(tail -1 "$PROGRESS_FILE" | cut -d' ' -f 3)
if [ $? -ne 0 ]; then
error_out "failed to read progress"
fi
}
case $(read_proress) in
step1)
echo do_sth_for_step1
;&
step2)
echo step2_thing
;&
step3)
echo step3_thing
;;
esac
答案 2 :(得分:0)
如果我理解你的话,你可以使用像eval fn$(cat status)
这样的东西。在每个函数的最后,您调用runnext
来派生当前函数的编号,添加1并通过eval
调用生成的函数。