我创建了一个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脚本中设置这些路径?
答案 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.tcsh
或script.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。一旦我清理干净,一切都很好。