我正在使用 bash shell,但我需要获取的一些脚本是 csh 格式的。有人能告诉我如何从 bash shell 获取 csh 脚本吗?
我所说的来源是指来源的 csh 脚本应该能够设置环境变量。因此,我想在我的 中执行如下操作~/.bashrc
:
source path/to/csh_script/script.cshrc
答案1
bash 无法完美运行所有 csh 脚本。可能存在一些基本重叠,例如非常基本的 bash 脚本可以在 sh/dash 中运行,但如果无法在 bash 中运行(使用 进行测试bash [file]
),则无法运行。要么
- 修改它们以在 bash 中运行,或者
使用从 bash 脚本调用的 csh 运行它们,就像在终端中运行它们一样,让它们返回结果值或执行它们应该执行的任何操作。正如您所评论的那样,这不会为主 bash 脚本留下任何可用的变量或函数,因此您要么
- 让他们对外部文件做任何他们应该做的事情,或者
- 返回单个值/字符串,或者可能
- 将它们视为另一个程序,并将多行输出读入你的 bash 脚本。
如果您只是想要获取源变量,理论上可以逐行浏览 csh 脚本并将变量添加到当前 bash shell/脚本中。类似于以下内容:
while read line
do
[stuff with $line]
done < /path/to/[the csh script to add]
我不知道您所获取的脚本中所有变量是如何布局的,因此由您来决定 [$line 的内容] 应该是什么。
如果他们像狂欢,那么可能只是 grep 任何以空格或字符开头的行,有一个
=
可选的更多没有空格的字符,所以:回显“$line”|
grep '^\s*\S*=\S*'
或者像上面一样在
=
with 之后添加任何内容:回显“$line”|
grep '^\s*\S*=.*'
但是我思考csh 变量都以set
/开头setenv
,因此可以找到 set/setenv 行,然后丢弃 set/setenv。尝试作为启动器:
echo "$line" | grep '^\s*\S*set.*=.*'
这些只是快速示例 grep / regex 模式,请参阅这&那&其他的了解更多信息。
或者,如果只有其中几个,请手动浏览它们并将所有变量粘贴到 bash/sh 兼容文件中,然后您可以在 bash 中毫无问题地进行源操作。
答案2
shebang 行已经帮你搞定了。当你运行#! /bin/csh -f
第一行包含 的脚本时,系统会将#!
部分识别为脚本,并加载其后指定的任何解释器(在本例中为/bin/csh
)。
或者,您可以使用 明确调用解释器csh /path/to/script.csh
。
这是一个小演示。我的交互式 shell 是mksh
,我正在调用一个简单的csh
脚本:
xieerqi:
$ cat bin/whiledemo.csh
#! /bin/csh -f
# demoloop.csh - Sample loop script
set j = 1
while ( $j <= 5 )
echo "Welcome $j times"
@ j++
end
xieerqi:
$ echo $SHELL
/bin/mksh
xieerqi:
$ bin/whiledemo.csh
Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times
xieerqi:
$ csh bin/whiledemo.csh
Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times
请注意,如果 前面有一个空格#!
, 就#!
不会被解释,因此脚本将使用您调用脚本的交互式 shell 运行。当然,您可以预料到脚本会失败,因为脚本和交互式 shell 期望的语法不同。在写这个答案的过程中,我遇到了这个确切的错误。
答案3
我不知道 csh,但我对 ksh 有类似的要求。我的 hack 解决方案是
eval source <(ksh -c ". /path/to/my_script.ksh
env|sort)
我遇到了引用问题,最终在 env 后面放入了一些 grep 模式来删除我不想延续的环境变量,但它有点起作用了。
我在这里发现了另一个有用的东西:
https://www.theunixschool.com/2010/07/how-to-access-child-shell-env-variable.html
sed 的这一小段代码可以创建正确引用的导出命令:
sed 's/^/export /;s/=/=\"/;s/$/\"/'