我无法在tcl shell中执行某些Linux命令.
例如 ...
1)
% exec "export MIBS=ALL"
couldn't execute "export MIBS=ALL": no such file or directory
%
Run Code Online (Sandbox Code Playgroud)
2)
% pwd
/root
%
Run Code Online (Sandbox Code Playgroud)
3)
% exec pwd
/root
%
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,为什么我无法执行命令..
这个命令在内核中没问题.
[root@6 ~]# export MIBS=ALL
[root@6 ~]#
Run Code Online (Sandbox Code Playgroud)
user000001
是正确的:export
是shell的内置并exec
执行内核系统调用来执行提供的命令,而不是调用shell来执行此操作.
因此,要解决您的问题,您必须显式调用shell:
exec /bin/sh -c {export MIBS=ALL; some_program}
Run Code Online (Sandbox Code Playgroud)
哪个some_program
程序应该MIBS
在运行时看到环境块中的变量.
关于上述呼吁的两个警告exec
:
它假设您的系统具有/bin/sh
符号链接或真正的shell二进制文件.并且可用的shell /bin/sh
必须了解-c
命令行选项.
如果您/bin/sh
不这样做,请使用其他路径名.
shell进程将由它生成exec
,然后它将执行通过shell的-c
命令行选项提供的脚本,然后shell将退出.您必须了解shell变量(导出的或其他的)仅存在于它们已创建的shell进程中,因此系列中的第二个调用
exec /bin/sh -c {export FOO=bar}
exec /bin/sh -c {set -u; echo $FOO}
Run Code Online (Sandbox Code Playgroud)
会爆炸,因为一旦第一个shell进程退出,FOO
变量就会随之消失,第二个/bin/sh
进程从你的Tcl进程中获取(继承)一个新的环境副本.
你应该从中得到的是你必须设置必要的环境变量并调用应该在传递给shell的同一脚本中看到它们的程序.
最后和无关的说明.
如果你的脚本很大,那么通过它的命令行不将它传递给shell是有意义的,而是通过它的标准输入传递给shell,如下所示:
set fd [open {|/bin/sh} r+]
puts $fd {
set -e -u
echo test
cat /path/to/whatever
...
}
# Read the shell's response
set out [read $fd]
# The following call will throw an exception if the shell
# exits with a non-zero exit code or wrote something to its
# standard error stream. You might want to [catch] it.
close $fd
Run Code Online (Sandbox Code Playgroud)
更新以包括Donal Fellows的建议:上面第二个警告的推论是,如果你修改自己的进程的环境(托管Tcl解释器)然后使用exec
生成的进程运行你的目标程序将继承你的环境变量你已安装到您自己进程的环境块中.因此,这也应该做的伎俩:
set ::env(MIBS) ALL
exec some_program
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
592 次 |
最近记录: |