【问题标题】:weird behaviour of If statement in (t)csh(t)csh 中 If 语句的奇怪行为
【发布时间】:2013-05-23 07:38:21
【问题描述】:

我有一个 if 循环并没有完全按照它应该做的那样做。 我希望 if 循环查找特定文件“if (-f JUN*[0-9].acc$RUN.nc)”,如果找到,则继续执行缩进的操作。 如果没有,它应该跳过 endif 并继续阅读脚本。

目前,它正在寻找文件 ok(它已经能够通过第一个“if”语句并在找到第一个文件时做正确的事情),但是一旦它没有找到什么它正在寻找,它会停止整个脚本并返回错误:

DEC*[0-9].accE01Ccek0kA.nc:不匹配。

我在不同的地方尝试了 if: ... else: pass 和 if ... then ... endif 和冒号等的各种组合,但我仍然无法正常工作。

感谢您的帮助!

  setenv RUN $1                                 # Run number
  setenv BDIR /discover/nobackup/cekrause
  setenv MONDATA $BDIR/$RUN/data_files # Target directory
  setenv DATADIR $BDIR/$RUN                  # Run directory
  setenv EXECDIR /discover/nobackup/projects/giss/exec

  cd $DATADIR

  #### pdE JUN and DEC files ####
  if (-f JUN*[0-9].acc$RUN.nc) then
       mkdir tempplot
       cp JUN*[0-9].acc$RUN.nc tempplot
       cd tempplot
       pdE JUN*[0-9].acc$RUN.nc
  endif

  cd $DATADIR

  if (-f DEC*[0-9].acc$RUN.nc) then
       mkdir tempplot
       cp DEC*[0-9].acc$RUN.nc tempplot
       cd tempplot
       pdE DEC*[0-9].acc$RUN.nc
  endif

  (do some other things)
  exit

【问题讨论】:

  • 或者,在终端中输入info bash
  • 顺便说一句:没有“if循环”之类的东西。 if 语句不会循环。如果你想要一个循环,请使用while
  • @Mat 很明显,Claire 使用 csh 而不是 bash 来执行脚本(当遇到 setenv 行时,bash 已经失败了)。 “bash”标签是错误的。

标签: if-statement csh


【解决方案1】:

您使用 csh 或 tcsh 而不是 bash,而您刚刚发现的有些不合理的行为是不使用 csh 进行编程的原因之一。而且还有更多。 Much more. 所以,请:当你写一个 shell 脚本时,永远不要使用 (t)csh。使用 bash、ksh、dash、zsh 或普通的旧 sh;他们都更适合这项任务。是的,语法与 csh 明显不同,因此您将不得不重写部分脚本,但这是有回报的。您的脚本应如下所示:

#!/bin/bash

export RUN=$1                                 # Run number
export BDIR=/discover/nobackup/cekrause
export MONDATA=$BDIR/$RUN/data_files          # Target directory
export DATADIR=$BDIR/$RUN                     # Run directory
export EXECDIR=/discover/nobackup/projects/giss/exec

cd "$DATADIR"

#### pdE JUN and DEC files ####
if [ -f JUN*[0-9].acc"$RUN".nc ] ; then   # note spaces around [, ], and semicolon before "then"
     mkdir tempplot
     cp JUN*[0-9].acc"$RUN".nc tempplot
     cd tempplot
     pdE JUN*[0-9].acc"$RUN".nc
fi                                        # bash uses "fi" instead of "endif"  

cd "$DATADIR"

if [ -f DEC*[0-9].acc"$RUN".nc ] ; then
     mkdir tempplot
     cp DEC*[0-9].acc"$RUN".nc tempplot
     cd tempplot
     pdE DEC*[0-9].acc"$RUN".nc
fi

(do some other things)
exit

【讨论】:

  • 非常感谢!难怪我遇到了这么多问题——我什至不知道我试图用什么语言编写代码(我从一个我有工作的脚本开始并试图修改它)。从现在开始我将转向 BASH,这似乎更有意义。感谢您的所有帮助!
【解决方案2】:

如果在 bash 中不是这样写的。它应该是这样的:

 if [ -f JUN*[0-9].acc$RUN.nc ] ; then

是的,请就此类问题查阅已有的在线资源。并不是没有一个网站有这些东西。

【讨论】:

  • 请记住,此代码仅在 最多一个 文件与该模式匹配时才有效。如果有两个或更多文件,您将收到语法错误。在这种情况下,您需要更复杂的东西,例如,数组赋值 FILES=(JUN*[0-9].acc$RUN.nc) ; 后跟测试 if [ -f "${FILES[0]}" ] ; then
  • 整个脚本不是 bash。如果你使用 bash 运行这个脚本,你会得到bash: setenv: command not found
【解决方案3】:

csh 中,如果像DEC*[0-9].accE01Ccek0kA.nc 这样的glob 无法匹配文件,那么您会收到No match 错误。这意味着您几乎不能将 -f 与 glob 一起使用。

很多最好使用bash 编写脚本,因为这样的问题很多。但是,如果您必须使用 csh,您可以通过以下方式克服这个特殊的怪癖:

set nonomatch

在使用任何 glob 之前。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多