实际上我想运行2个批处理脚本,第一个脚本将设置一个系统变量set NEWPATH="E:/Some"
,第二个脚本将显示该变量的路径:echo %NEWPATH%
。在同一台服务器上第一次无法正常工作,只有在重新启动服务器后才能显示路径,否则什么也不会显示。请问是否有人能帮我解决这个问题?
实际上我想运行2个批处理脚本,第一个脚本将设置一个系统变量set NEWPATH="E:/Some"
,第二个脚本将显示该变量的路径:echo %NEWPATH%
。在同一台服务器上第一次无法正常工作,只有在重新启动服务器后才能显示路径,否则什么也不会显示。请问是否有人能帮我解决这个问题?
首先启动了一个cmd.exe
进程,执行了一个批处理脚本,设置了一个环境变量;然后该进程消失,它的环境块也随之消失。
接着又启动了另一个cmd.exe
进程,继承了您主机进程(编写Go)的环境块,但是可以看到,第一个批处理脚本设置的任何内容都不可用。
有两种可能的解决方法:
Make the first batch script call the second one by itself.
In this case the second cmd.exe
will inherit the environment variables
set by the first script and will hence "see" them.
Note that the Windows batch command language supports the calls
command to call out to other batch scripts by their pathnames.
Make the first script communicate the value of that variable to your host process and then arrange in the host process for the second cmd.exe
to have the indicated variable with the indicated value in its environment.
Say, the first script could just do something like
echo VARNAME=value
to have
VARNAME=value
printed to its stdout.
Your Go process could parse that output, tear it apart on the =
character, sanitize to not affect "interesting" variables like PATH
,
USERPROFILE
etc, and then the host process could do
env := os.Environ()
env = env.append("VARNAME=value") // real value here
...
cmd := exec.Command(`cmd.exe`, `/c`, secondScriptFilePath)
cmd.Env = env
...
cmd.Run() // or whatever
os.Setenv("VARNAME=value")
将此变量显示在其自己的环境块中;然后,它将自动继承启动后的任何进程。
更新以解决OP的评论
…脚本文件将在客户端中,因此我无法添加一行
echo VARNAME=value
。那么还有其他可能的方法吗?
在您的情况下,还有另一种方法可能有效。
想法是cmd.exe
只是一个Shell:当它以非交互方式启动时(这就是exec.Command("cmd.exe")
所做的),它从其标准输入流读取命令并逐个执行它们-直到流被发送方关闭为止。
因此,您可以执行以下操作:
使用 io.Pipe
将一个实例连接到 cmd.exe
的 Stdin
上来启动 cmd.exe
。
打开第一个脚本并通过在第一步设置的管道将其传输到正在运行的 cmd.exe
中。
不要忘记对该管道进行 Flush()
操作。
您可以使用 io.Copy()
函数,该函数将从已打开的 io.Reader
发送所有数据到某个 io.Writer
。
保留 shell 实例运行状态。
在适当的时候读取第二个脚本并将其传输到同一个 shell 中。
由于使用的是同一个 shell,因此第二个脚本将会像物理附加到第一个脚本一样运行,并且可以访问第一个脚本设置的所有变量。
setx
命令,该命令可以在用户或系统上下文中永久设置环境变量(这是第三种可能的方式,@kostix)... - aschipflsetx
命令?(这可以解释为什么“当我重新启动服务器时,它会显示路径,否则它将什么也不显示”这句话对我来说有些难以理解)。 - kostix// 从这里读取错误,你会注意到kill fmt.Println(err)
}..我在func two()中做了同样的事情 - shagul