【问题标题】:tcsh: foreach command works fine in Terminal, but doesn't work when called from a tcsh script filetcsh:foreach 命令在终端中运行良好,但在从 tcsh 脚本文件调用时不起作用
【发布时间】:2013-12-16 17:41:54
【问题描述】:

有关问题的简化版本,请先阅读下面的 Update1。

我制作了一个 tcsh 文件,以将其运行的文件夹中所有文件/文件夹的列表保存到一个文件中(我正在处理一个神经影像学项目,并且我的文件夹 RawData 包含许多主题每个都有一个文件夹;我已经编写了这个文件 genSubjList.tcsh 来将主题列表保存到文件 subjList.txt)。文件里面的代码是:

foreach subj (*)
    echo $subj >> subjList.txt
end

当我切换到终端中的 RawData 目录并在终端中编写这段代码时,它会毫无问题地生成主题列表,但是当我使用 source 命令调用 genSubjList.tcsh 时:

source ../scripts/genSubjList.tcsh

它只是将 RawData 中第一个文件夹(主题)的名称写入 subjList.txt;我已经使用 chmode +x 使 genSubjList.tcsh 可执行(“scripts”文件夹在 RawData 的父文件夹中,包含 genSubjList.tcsh)

我在终端内运行代码时的输出是文件 subjList.txt 包含:

主题1 主题2 主题3 . . . 主题n

当我使用 source ../scripts/genSubjLits.tcsh 运行代码时的输出是文件 subjList.txt 包含:

主题1

如果能帮助我找出错误所在,我将不胜感激。谢谢!

关于我为什么要找出问题所在的补充说明:

问题不仅仅在于生成主题列表;我想了解为什么这个 tcsh 脚本不起作用,因为主要问题是我正在使用 FreeSurfer (surfer.nmr.mgh.harvard.edu) 来分析一些主题;我想并行分析它们,所以我开发了一些脚本将主题分为 5 个组(存储在 5 个名为 subjList1.txt .. subjList5.txt 的文件中,每个文件都有多个主题)。然后,我想在 5 个终端中并行运行以下代码:

foreach subj (`cat subjList1.txt`)
    echo $subj
    recon-all -i $RAW_DATA/$subj/T1/*0001.dcm -subject $subj -all
end

其中 subjList1.txt 被 subjList2、3 等替换为并行终端; recon-all 行对每个主题进行分析。同样,当我在终端中运行这段代码时,会分析每个 subjList 中的所有主题,但是当我将同一段代码保存在多个脚本文件(recon1.tcsh .. recon5.tcsh)中并使用调用它们时:

source recon1.tcsh

只分析每个 subjList 中的第一个主题。

更新1:

有趣的是,如果这个简单的循环:

foreach i (1 2 3 4 5)
    echo $i
end

存储在文件 loop.tcsh 中,并使用以下方法调用:

source loop.tcsh

输出将只有 1,这意味着它只是通过第一轮循环。

同样的问题在 BASH 中不存在;如果这个循环:

for i in {1..5} ; do
    echo $i
done

存储在文件 loop2.bash 中并使用:

source loop2.bash

它没有任何问题!

更新2:

BASH 中不存在该问题;如果这段代码:

for subj in * ; do
    echo $subj >> subjList.txt
done

存储在文件 genSubjList.bash 中并使用:

source ../scripts/genSubjList.bash

在bash环境下,生成主题列表没有问题!

【问题讨论】:

  • 您确定在这两种情况下都在同一目录中运行foreach 循环吗?可以肯定的是,尝试在foreach 的正上方添加一个pwd 命令。
  • 感谢您的回复;我在 foreach 上方(和循环内部)添加了 pwd,它表明循环在同一目录中运行。

标签: shell foreach tcsh


【解决方案1】:

我知道这很旧,但我遇到了这个问题,因为我刚才遇到了同样的问题,我自己解决了。

我在 tcsh foreach 脚本的“结束”之后添加了一个空行,它运行良好。在此之前,它只会遍历列表中的第一项,然后停止。 Bash 脚本对我来说效果很好,就像原始海报一样。为什么空行很重要?

【讨论】:

  • 我认为问题在于 tcsh 是行缓冲的。如果您以不以换行符结尾的行结束脚本,则不会读取该行。
【解决方案2】:

考虑到您从源命令运行此命令时的输出仅生成列表中的第一个主题,我会检查是否存在循环问题。因为您不再与从终端运行它时位于同一个目录中,所以脚本可能不会返回到同一个主目录。我会在你的 for 循环的最后一行添加一个 CD 命令,看看是否能解决问题。

【讨论】:

  • 感谢您的回复;我按照您的建议修改了代码,并将 cd $PWD 行添加为循环的最后一行,但不幸的是问题仍然存在。
【解决方案3】:

嗯...而不是密码,也许尝试将整个路径写入您希望脚本从/返回到的位置。如果问题是由于没有返回到正确的目录,那么 cd pwd 将使您留在同一个地方并且无法解决问题。

【讨论】:

  • 再次感谢您一直以来的帮助;我再次尝试了整个路径,但问题仍然存在。
猜你喜欢
  • 2014-12-20
  • 2021-12-14
  • 1970-01-01
  • 2020-03-09
  • 2019-03-23
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多