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。仅将其用作最后的手段,并且仅在您可以控制 eval
ed.
字符串的情况下使用
不满者很容易传入将由 eval
执行的有害代码。
(抱歉,我手头没有 csh
来测试这个,所以如果您遇到问题请告诉我)。
最后,阅读广泛发表的文章,这些文章表明 csh
不是一种很好的编程语言。在您方便的时候尽早切换到 bash
或 ksh
。你不会后悔的。
IHTH
如果未设置其中一个变量,您的脚本将崩溃;在 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
正如 shell 之三的回答提到的那样,除非您完全控制传递给它的内容,否则 eval
可能不安全。在这种特殊情况下,这不是问题。
另一种可能的解决方案可能是解析 printenv
的输出——但如果某些环境变量的值包含换行符等奇怪字符,这可能 运行 会出现问题。
或者您可以用另一种语言编写和调用一个小程序;例如 C 的 getenv()
或 Perl 的 %ENV
不需要使用 eval
来确定是否设置了任意环境变量,并且不易受到具有奇怪字符的值的影响。
我依稀记得在某些旧版本的csh 中,$?VAR
语法仅适用于shell 变量,不适用于环境变量。它确实适用于 tcsh 和更现代的 csh 版本。
我有一个 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。仅将其用作最后的手段,并且仅在您可以控制 eval
ed.
不满者很容易传入将由 eval
执行的有害代码。
(抱歉,我手头没有 csh
来测试这个,所以如果您遇到问题请告诉我)。
最后,阅读广泛发表的文章,这些文章表明 csh
不是一种很好的编程语言。在您方便的时候尽早切换到 bash
或 ksh
。你不会后悔的。
IHTH
如果未设置其中一个变量,您的脚本将崩溃;在 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
正如 shell 之三的回答提到的那样,除非您完全控制传递给它的内容,否则 eval
可能不安全。在这种特殊情况下,这不是问题。
另一种可能的解决方案可能是解析 printenv
的输出——但如果某些环境变量的值包含换行符等奇怪字符,这可能 运行 会出现问题。
或者您可以用另一种语言编写和调用一个小程序;例如 C 的 getenv()
或 Perl 的 %ENV
不需要使用 eval
来确定是否设置了任意环境变量,并且不易受到具有奇怪字符的值的影响。
我依稀记得在某些旧版本的csh 中,$?VAR
语法仅适用于shell 变量,不适用于环境变量。它确实适用于 tcsh 和更现代的 csh 版本。