我有一个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
但这显然不起作用。
答案 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
不是编程的好语言。尽早切换到bash
或ksh
。你不会后悔的。
IHTH
答案 1 :(得分:3)
如果未设置其中一个变量,您的脚本将崩溃;在csh / tcsh中引用未定义的变量是一个错误。 (这与sh / bash不同,如果未设置变量,$FOO
默认会扩展为空字符串。)
如果您可以安全地假设所有相关变量都已设置,那么shellter的解决方案应该没问题。如果你想做一些错误检查,请继续阅读。
用于测试变量$VAR
是否已定义的csh / tcsh语法是$?VAR
。它评估为0
或1
。
一个例子:
#!/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中都有效。