如何从特定行启动shell脚本?

时间:2015-04-09 13:31:49

标签: linux shell

#!/bin/sh
echo "install 1"
echo "install 2"
[ $? -eq 0 ] || exit $?;
cyberciti 
[ $? -eq 0 ] || exit $?;
echo "install 3"
echo "install 4"

上述脚本在第4行(cyberciti)失败。在进行必要的更正后,如何跳过已执行的命令,如何获取行号,并从该行开始重新运行脚本?

3 个答案:

答案 0 :(得分:8)

要跳过前4行(因此从第5行开始):

tail --lines=+5 script.sh | sh

根据the man page--lines=K表示output the last K lines, instead of the last 10; or use -n +K to output starting with the Kth

他的回答Aaron Digulla会转到here。编辑:感谢l0b0阻止我的cat taking over the world

答案 1 :(得分:1)

当您认为经常需要做这样的事情时,您可以使用特殊变量。并创建一个可选的命令行参数(默认从开头开始),告诉您从哪里开始 非结构化版本看起来像:

#!/bin/sh
if [ $# -eq 1 ]; then
   PHASE=$1
else
   PHASE=1
fi
echo phase $PHASE

if [ ${PHASE} -eq 1 ]; then
        echo "install 1"
        (( PHASE = PHASE + 1 ))
fi

if [ ${PHASE} -eq 2 ]; then
        echo "install 2"
        [ $? -eq 0 ] || exit $?;
        (( PHASE = PHASE + 1 ))
fi

if [ ${PHASE} -eq 3 ]; then
        echo cyberciti
[ $? -eq 0 ] || exit $?;
        # Still phase 3, cyberciti is not a special phase

        echo "install 3"
        (( PHASE = PHASE + 1 ))
fi

if [ ${PHASE} -eq 4 ]; then
        echo "install 4"
        (( PHASE = PHASE + 1 ))
fi

改进将使用while循环:

#!/bin/sh
if [ $# -eq 1 ]; then
   PHASE=$1
else
   PHASE=1
fi

function phase2 {
        echo "install 2"
        [ $? -eq 0 ] || exit $?;
}

function phase3 {
        echo cyberciti
        [ $? -eq 0 ] || exit $?;
        # Still phase 3, cyberciti is not a special phase
        echo "install 3"
}

while [ ${PHASE} -lt 5 ]; do
        [ ${PHASE} -eq 1 ] && echo "install 1"
        [ ${PHASE} -eq 2 ] && phase2
        [ ${PHASE} -eq 3 ] && phase3
        [ ${PHASE} -eq 4 ] && echo "install 4"
        (( PHASE = PHASE + 1 ))
done

进一步的改进可能包括逻辑名称和一些可在阶段内改变的特殊流量控制。

编辑:使用案例构建进行改进

#!/bin/sh
if [ $# -eq 1 ]; then
   PHASE=$1
else
   PHASE=1
fi

function phase2 {
        echo "install 2"
        [ $? -eq 0 ] || exit $?;
}

function phase3 {
        echo cyberciti
        [ $? -eq 0 ] || exit $?;
        # Still phase 3, cyberciti is not a special phase
        echo "install 3"
}

endloop=false
while [ ${endloop} = false ]; do
   case ${PHASE} in
       1) echo "install 1" ;;
       2) phase2 ;;
       3) phase3 ;;
       4) echo "install 4" ;;
       5) endloop=true ;;
       *) echo "Phase ${PHASE} not supported" ;;
    esac
    (( PHASE = PHASE + 1 ))
done

答案 2 :(得分:0)

#!/bin/sh
if [ $# -eq 1 ]; then
 PHASE=$1
else
 PHASE=1
fi
if [ ${PHASE} -le 6 ]; then
    echo "install 1 "
    echo "install 2 "
fi
if [ ${PHASE} -le 10 ]; then
  cyberciti
  [ $? -eq 0 ] || exit $?;
  echo "install 3 "
  [ $? -eq 0 ] || exit $?;
fi
if [ ${PHASE} -le 16 ]; then
    echo "install 4"
    [ $? -eq 0 ] || exit $?;
fi

这是我需要的最终脚本,当我们第一次运行时( sh test.sh )将在cyberciti失败,那么我们只需要在用有效命令替换cyberciti之后从这一行运行,所以它从这一行恢复运行,新参数为错误行( sh test.sh 11