csh中有没有办法动态检查环境变量?

Is there a way in csh to dynamically check environment variables?

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

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

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

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

我尝试这样做来检验理论:

#!/bin/csh -f

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

但这显然行不通。

您只缺少一个 \ 字符,即

#!/bin/csh -f

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

我在这里添加了一个 echo 以便 eval 可以做一些安全但可见的事情。

更改您的 shebang 行以使用 debug/trace 模式,即

#!/bin/csh -fvx

并定义

     SOMETHING=abc

你会看到 eval 完成的两次传球,你会(应该)看到 其中

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

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

最后,不要依赖于使用 eval。仅将其用作最后的手段,并且仅在您可以控制 evaled.

字符串的情况下使用

不满者很容易传入将由 eval 执行的有害代码。

(抱歉,我手头没有 csh 来测试这个,所以如果您遇到问题请告诉我)。

最后,阅读广泛发表的文章,这些文章表明 csh 不是一种很好的编程语言。在您方便的时候尽早切换到 bashksh。你不会后悔的。

IHTH

如果未设置其中一个变量,您的脚本将崩溃;在 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

正如 shell 之三的回答提到的那样,除非您完全控制传递给它的内容,否则 eval 可能不安全。在这种特殊情况下,这不是问题。

另一种可能的解决方案可能是解析 printenv 的输出——但如果某些环境变量的值包含换行符等奇怪字符,这可能 运行 会出现问题。

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

我依稀记得在某些旧版本的csh 中,$?VAR 语法仅适用于shell 变量,不适用于环境变量。它确实适用于 tcsh 和更现代的 csh 版本。