在csh中有一种方法可以动态检查环境变量吗?

时间:2015-01-26 17:58:26

标签: csh

我有一个c应用程序调用带有大量信息的csh脚本。我想以这样的方式扩展它,使csh脚本可以循环遍历环境变量。例如,c应用程序将设置以下envs

COUNT=4
SOMETHING_1=HELLO
SOMETHING_2=WORLD
SOMETHING_3=WIDE
SOMETHING_4=WEB

csh脚本可以遍历SOMETHING并根据计数env打印出env。

是否可以评估以编程方式生成的env?

我试着这样做来测试这个理论:

#!/bin/csh -f

foreach n ( 1 2 3 4 )
        eval "$SOMETHING"_"$n"
end

但这显然不起作用。

2 个答案:

答案 0 :(得分:3)

你所缺少的只是一个\字符,即

#!/bin/csh -f

foreach n ( 1 2 3 4 )
        eval echo \$"SOMETHING"_"$n"
        # --------^--- here
end

我在这里添加了echo,以便eval有一些安全但可见的内容。

更改你的shebang线以使用调试/跟踪模式,即

#!/bin/csh -fvx

并定义

     SOMETHING=abc

你会看到eval所做的两次传球,你应该看到的

 echo $SOMETHING_1
 echo "value of abc_1 =$abc_1 XXX"

但当然,您必须为变量abc_1定义一个值。

最后,不要依赖使用eval。仅将其用作最后的手段,并且只有在您可以控制eval编辑的字符串的情况下才能使用它。

不满情绪很容易传递将由eval执行的有害代码。

(对不起,我没有csh方便测试这个,所以如果你有麻烦请告诉我。)

最后,阅读广泛发表的文章csh不是编程的好语言。尽早切换到bashksh。你不会后悔的。

IHTH

答案 1 :(得分:3)

如果未设置其中一个变量,您的脚本将崩溃;在csh / tcsh中引用未定义的变量是一个错误。 (这与sh / bash不同,如果未设置变量,$FOO默认会扩展为空字符串。)

如果您可以安全地假设所有相关变量都已设置,那么shellter的解决方案应该没问题。如果你想做一些错误检查,请继续阅读。

用于测试变量$VAR是否已定义的csh / tcsh语法是$?VAR。它评估为01

一个例子:

#!/bin/tcsh -f

setenv SOMETHING_1 foo
setenv SOMETHING_3 bar

foreach i (1 2 3 4 5)
    set is_set = `eval echo '$?SOMETHING_'$i`
    if ($is_set) then
        echo '$SOMETHING_'$i is set to `eval echo '$SOMETHING_'$i`
    else
        echo '$SOMETHING_'$i is not set
    endif
end

输出:

$SOMETHING_1 is set to foo
$SOMETHING_2 is not set
$SOMETHING_3 is set to bar
$SOMETHING_4 is not set
$SOMETHING_5 is not set

正如shellter的回答所提到的,eval可能不安全,除非您完全控制传递给它的内容。在这个特殊情况下,这不是问题。

另一种可能的解决方案可能是解析printenv的输出 - 但如果某些环境变量的值具有奇怪的字符(如换行符),则可能会遇到问题。

或者你可以用另一种语言编写和调用一个小程序;例如,C的getenv()或Perl的%ENV不需要使用eval来确定是否设置了任意环境变量,并且不容易受到具有奇怪字符的值的影响。< / p>

我含糊地回忆起在某些旧版本的csh中,$?VAR语法仅适用于shell变量,而不适用于环境变量。它在tcsh和更现代版本的csh中都有效。