Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何跳过以前成功运行的行重新运行bash脚本?_Linux_Bash - Fatal编程技术网

Linux 如何跳过以前成功运行的行重新运行bash脚本?

Linux 如何跳过以前成功运行的行重新运行bash脚本?,linux,bash,Linux,Bash,我有一个bash脚本,它充当分析管道的包装器。如果脚本出错,我希望能够通过简单地重新运行原始命令,从错误发生的位置运行脚本。我设置了两个不同的陷阱;一个将从我的脚本中删除非零退出时生成的最后一个文件,另一个将在退出信号=0时删除所有临时文件,并在运行结束时基本上清理文件系统。我在bash环境中打开了noclobber,它允许我的脚本跳过脚本中已写入文件的行,但只有在我没有设置非零退出陷阱的情况下才会这样做。一旦我设置了这个陷阱,它就会在第一行退出,在那里noclobber标识了一个它不会覆盖的文

我有一个bash脚本,它充当分析管道的包装器。如果脚本出错,我希望能够通过简单地重新运行原始命令,从错误发生的位置运行脚本。我设置了两个不同的陷阱;一个将从我的脚本中删除非零退出时生成的最后一个文件,另一个将在退出信号=0时删除所有临时文件,并在运行结束时基本上清理文件系统。我在bash环境中打开了noclobber,它允许我的脚本跳过脚本中已写入文件的行,但只有在我没有设置非零退出陷阱的情况下才会这样做。一旦我设置了这个陷阱,它就会在第一行退出,在那里noclobber标识了一个它不会覆盖的文件。有没有一种方法可以让我跳过以前成功运行过的代码行,而不必从一开始就重新运行代码?我知道我可以对每一行使用条件语句,但我认为可能有更简洁的方法

set -o noclobber

# Function to clean up temporary folders when script exits at the end
rmfile() { rm -r $1 }

# Function to remove the file being currently generated
# Function executed if script errors out

rmlast() {
if [ ! -z "$CURRENTFILE" ]
then
rm -r $1
exit 1
fi }

# Trap to remove the currently generated file
trap 'rmlast "$CURRENTFILE"' ERR SIGINT

#Make temporary directory if it has not been created in a previous run
TEMPDIR=$(find . -name "tmp*")
if [ -z "$TEMPDIR" ]
then
TEMPDIR=$(mktemp -d /test/tmpXXX)
fi

# Set CURRENTFILE variable
CURRENTFILE="${TEMPDIR}/Variants.vcf"

# Set CURRENTFILE variable
complexanalysis_tool input_file > $CURRENTFILE

# Set CURRENTFILE variable
CURRENTFILE="${TEMPDIR}/Filtered.vcf"

complexanalysis_tool2 input_file2 > $CURRENTFILE

CURRENTFILE="${TEMPDIR}/Filtered_2.vcf"

complexanalysis_tool3 input_file3 > $CURRENTFILE

# Move files to final destination folder
mv -nv $TEMPDIR/*.vcf /test/newdest/

# Trap to remove temporary folders when script finishes running
trap 'rmfile "$TEMPDIR"' 0
更新:

我得到了建议使用make实用程序的答案。我想利用它的内置实用程序来检查是否满足了依赖关系。 在我看来,VK Kashyap建议的makefile似乎不会跳过以前完成的任务的执行。例如,我运行了上面的脚本,并在使用ctrl c运行filter.vcf时中断了脚本。当我再次运行脚本时,它会从头开始再次运行,即在varaints.vcf重新启动。为了让makefile将源代码显示为已满,我是否遗漏了什么

更新的答复:

好的,这是一个新手的错误,但由于我不熟悉生成makefile,我将发布我的错误解释。我的makefile没有从退出点重新运行的原因是,我为目标命名了与正在生成的输出文件不同的名称。因此,如果你说出目标,VK Kashyap的回答非常正确

variants.vcf
filtered.vcf
filtered2.vcf

与生成的输出文件相同,脚本将跳过以前完成的任务。

make实用程序可能是您想要实现的目标的答案

它具有内置的依赖性,用于检查您试图使用tmp文件获取的内容

#run all target when all of the files are available
all: variants.vcf filtered.vcf filtered2.vcf
   mv -nv $(TEMPDIR)/*.vcf /test/newdest/

variants.vcf:
    complexanalysis_tool input_file > variants.vcf

filtered.vcf:
    complexanalysis_tool2 input_file2 > filtered.vcf

filtered2.vcf:
    complexanalysis_tool3 input_file3 > filtered2.vcf
您可以使用bash脚本调用此make文件,如下所示:

#/bin/bash

export TEMPDIR=xyz
make -C $TEMPDIR all
make实用程序将检查自身是否已完成任务,并跳过已完成任务的执行。它将在您完成任务时出错的地方继续


您可以在internet上找到有关makefile确切语法的更多详细信息。

make utility可能是您想要实现的目标的答案

它具有内置的依赖性,用于检查您试图使用tmp文件获取的内容

#run all target when all of the files are available
all: variants.vcf filtered.vcf filtered2.vcf
   mv -nv $(TEMPDIR)/*.vcf /test/newdest/

variants.vcf:
    complexanalysis_tool input_file > variants.vcf

filtered.vcf:
    complexanalysis_tool2 input_file2 > filtered.vcf

filtered2.vcf:
    complexanalysis_tool3 input_file3 > filtered2.vcf
您可以使用bash脚本调用此make文件,如下所示:

#/bin/bash

export TEMPDIR=xyz
make -C $TEMPDIR all
make实用程序将检查自身是否已完成任务,并跳过已完成任务的执行。它将在您完成任务时出错的地方继续


您可以在internet上找到有关makefile确切语法的更多详细信息。

没有内置的方法可以做到这一点

但是,您可以通过跟踪最后一个成功的行并构建自己的goto语句来编写类似的内容,如中所述,只需将“标签”替换为实际的行号即可

然而,问题是这是否真的是一个聪明的想法

更好的方法是只运行所需的命令,而不是尚未执行的命令。 这可以通过bash脚本中的显式条件实现:

produce_if_missing() {
   # check if first argument is existing
   # if not run the rest of the arguments and pipe it into the first one
   local curfile=$1
   shift
   if [ ! -e "${curfile}" ]; then
     $@ > "${curfile}"
   fi
}

produce_if_missing Variants.vcf complexanalysis_tool input_file
produce_if_missing Filtered.vcf complexanalysis_tool2 input_file2
或者使用专门为这些事情设计的工具,请参见VK Kahyap使用make的答案,尽管我更喜欢使用make规则中的变量来最小化打字错误:

Variants.vcf: input_file
    complexanalysis_tool $^ > $@
Filtered.vcf: input_file
    complexanalysis_tool2 $^ > $@

没有内置的方法可以做到这一点

但是,您可以通过跟踪最后一个成功的行并构建自己的goto语句来编写类似的内容,如中所述,只需将“标签”替换为实际的行号即可

然而,问题是这是否真的是一个聪明的想法

更好的方法是只运行所需的命令,而不是尚未执行的命令。 这可以通过bash脚本中的显式条件实现:

produce_if_missing() {
   # check if first argument is existing
   # if not run the rest of the arguments and pipe it into the first one
   local curfile=$1
   shift
   if [ ! -e "${curfile}" ]; then
     $@ > "${curfile}"
   fi
}

produce_if_missing Variants.vcf complexanalysis_tool input_file
produce_if_missing Filtered.vcf complexanalysis_tool2 input_file2
或者使用专门为这些事情设计的工具,请参见VK Kahyap使用make的答案,尽管我更喜欢使用make规则中的变量来最小化打字错误:

Variants.vcf: input_file
    complexanalysis_tool $^ > $@
Filtered.vcf: input_file
    complexanalysis_tool2 $^ > $@

谢谢VK Kashyap和Ulmäute。我在两个答案上都做了标记,因为这两个答案都给了我可以使用的选择。我并没有真正考虑这个实用工具,谢谢你把这个介绍给我。如果你喜欢,那就酷吧。然而,接受答案的正确方式是接受它,选择最能帮助你的答案,谢谢你,VK Kashyap和Ulmäute。我在两个答案上都做了标记,因为这两个答案都给了我可以使用的选择。我并没有真正考虑这个实用工具,谢谢你把这个介绍给我。如果你喜欢,那就酷吧。然而,正确的接受方式 答案是接受它,选择对你帮助最大的一个