为什么这个tcsh shell脚本在设置PATH LD_LIBRARY_PATH时发出错误

时间:2011-11-17 16:32:18

标签: shell scripting tcsh

我创建了一个tcsh shell脚本,如下所示:

#!/bin/tcsh

setenv PATH  ""
setenv PATH  .:$HOME/bin:/usr/sbin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/cuda/bin:/usr/local/bin:/usr/bin:$PATH

setenv LD_LIBRARY_PATH ""
setenv LD_LIBRARY_PATH .:/usr/local/cuda/lib:/usr/local/cuda/lib64/:/usr/local/cuda:/usr/lib:/usr/lib32:/usr/local/cuda/bin:/usr/local/lib/:${LD_LIBRARY_PATH}

然后我让这个脚本可执行,当我尝试将其作为

执行时

./ script.sh,它会出现以下错误:

script.sh:3:setenv:not found

script.sh:4:setenv:not found

script.sh:6:setenv:not found

script.sh:7:setenv:not found

任何指针,如何在我的shell脚本中设置这些路径?

3 个答案:

答案 0 :(得分:4)

我的系统上没有出现同样的错误。

更新:请参阅最后两段,以便最好地了解正在发生的事情。

我最初的最佳猜测是你可以通过改变shebang来解决问题

#!/bin/tcsh

#!/bin/tcsh -f

(或使用

#!/bin/csh -f

tcsh添加到原始csh的功能主要用于交互式使用而不是脚本。)

-f选项告诉tcsh 而不是在启动时处理您的.login.cshrc.tcshrc文件。通常,您不希望脚本执行此操作;它使脚本的行为依赖于您自己的环境设置。也许你的.login中有一些东西与setenv做了一些奇怪的事情,尽管我想不出它可能是什么。尝试添加-f,看看是否有帮助。即使它没有,你也应该这样做。

(不要将-f用于/bin/sh/bin/bash脚本;它意味着其他内容,而且不需要。)

其他一些观察结果:

$PATH$LD_LIBRARY_PATH设置为空字符串是没用的。只需删除这两行。

编辑:

重新阅读你的问题后,我会看到你在那里做什么。您将$PATH设置为空字符串,然后为其添加更多文本:

setenv PATH ""
setenv PATH this:that:$PATH

这比我想象的更有意义,但编写一个命令仍然更简单:

setenv PATH this:that

.特别是开头放置$PATH是一个坏主意。想想如果你在一个目录中运行脚本会发生什么事情,在该目录中有人存放了令人讨厌的命令名ls。如果要在当前目录中执行命令,请使用./command。 (将.放在$PATH end 更安全,但仍然不是一个好主意。)

(并且使用tcsh或csh作为脚本语言(而不是交互式shell)被广泛认为是一个坏主意。This article,即使它没有说服你放弃tcsh脚本,至少会让你意识到陷阱。)

哦,如果它是一个tcsh脚本,你为什么称它为script.sh?在类Unix系统中不需要文件名的后缀(与Windows不同),但通常.sh后缀表示它是Bourne shell脚本。称之为script.tcshscript.csh,或仅script

编辑:

仔细查看您收到的错误消息,看起来错误来自/bin/sh不是来自tcsh。

在我的系统上,当我将setenv更改为Setenv(一个不存在的命令)时,使用tcsh运行脚本会给我:

Setenv: Command not found.
Setenv: Command not found.
Setenv: Command not found.
Setenv: Command not found.

与您向我们展示的错误消息不符。当我以/bin/sh foo.tcsh显式运行它时(单独留下setenv个命令),我得到:

foo.tcsh: 3: setenv: not found
foo.tcsh: 4: setenv: not found
foo.tcsh: 6: setenv: not found
foo.tcsh: 7: setenv: not found

与你得到的错误格式相符。

你说/bin/tcsh --version给出了正确的结果,所以这不是问题所在。不知何故,脚本由/bin/sh执行,而不是由tcsh执行。

这是我对正在发生的事情的最佳猜测。您正在使用Cygwin或MSYS,但是您从cmd shell调用脚本,而不是从Cygwin shell调用脚本。您的Windows系统已配置为识别.sh后缀以指示该文件是由C:\cygwin\bin\sh.exe执行的脚本(如前所述,文件后缀在Unix上通常不重要,或者在Cygwin环境,但它们在Windows上运行。)

最简单的解决方案可能是重写脚本以符合Bourne shell语法。但应该有办法让Windows调用Cygwin的tcsh来执行它。如果我猜对了,请告诉我们,我们可以提出解决方案。

答案 1 :(得分:2)

我的脚本没有任何问题。它在我的盒子上工作正常。

错误(我能想到)的唯一原因是tcsh在某种程度上不被用作解释器。

如果我在#!/bin/tcsh之前添加换行符,我可以重现错误。当shebang不是文件中的第一个字符时,解释器指令不会生效并使用您当前的shell(我猜测您的剪切不是c-shell变体(csh或tcsh)?)。

因此,检查#!/bin/tcsh确实是文件中的第一行,之前没有空格。


要确定实际使用哪个解释器,请尝试将其添加到您的脚本中:

echo "$shell"  ## prints shell name if tcsh or csh
echo "$BASH"   ## prints /bin/bash if bash

示例:

[me@home]$ bash x.sh  # run using bash

/bin/bash

[me@home]$ tcsh x.sh # run using tcsh
/bin/tcsh
BASH: Undefined variable.

答案 2 :(得分:1)

刚刚遇到这个问题,结果是由于脚本文件有Windows EOLs。一旦我清理干净,一切都很好。