您希望 csh 脚本中的设置应用于调用它的 sh 脚本。
基本上,你不能这样做,尽管有一些(相当丑陋的)方法可以让它发挥作用。如果您执行您的 csh 脚本,它将在运行脚本的进程的上下文中设置这些变量;一旦返回给调用者,它们就会消失。
您最好的选择是简单地编写一个新版本的 csh 脚本作为 sh 脚本,并从调用 sh 脚本中 source 或 .。
你可以翻译你的 csh 脚本:
#!/bin/csh -f
setenv TEST 1234
set path = /home/user/sandbox
到这里:
export TEST=1234
export PATH=/home/user/sandbox
(csh 专门处理 shell 数组变量 $path,将其绑定到环境变量 $PATH。sh 及其派生词不这样做,它们直接处理 $PATH 本身。)
请注意,要获取源的脚本不应在顶部有#! 行,因为在自己的进程中执行它没有意义;你需要在调用者的上下文中执行它的内容。
如果维护两个脚本副本,一个是来自 csh 或 tcsh 脚本的 sourced,另一个是来自 sh/ksh/bash/zsh 脚本的 sourced 或 .ed,这是不实际的,还有其他解决方案。例如,您的脚本可以打印一系列要执行的sh 命令;然后你可以做类似的事情
eval `./foo.csh`
(行尾会在这里造成一些问题)。
或者您可以修改 csh 脚本,使其设置所需的环境变量,然后调用一些指定的命令,这可能是一个新的交互式 shell;这很不方便,因为它不会在您正在运行的交互式 shell 中设置这些变量。
如果一个软件包需要设置一些特殊的环境变量,通常的做法是提供脚本,例如setup.sh和setup.csh,这样sh/ksh/bash/zsh用户可以这样做:
. /path/to/package/setup.sh
而 csh/tcsh 用户可以这样做:
source /path/to/package/setup.csh
顺便说一句,这个命令:
set path = /home/user/sandbox
在您的示例脚本中可能不是一个好主意。它替换整个$PATH 只用一个目录,这意味着您将无法执行像ls 这样的简单命令,除非您指定它们的完整路径。你通常想要这样的东西:
set path = ( $path /home/user/sandbox )
或者,在 sh 中:
PATH=$PATH:/home/user/sandbox