实际上我想运行2个bat脚本,第一个脚本将设置系统变量set NEWPATH="E:/Some"
,第二个脚本将显示该变量的路径:echo %NEWPATH%
。这不是第一次使用同一台服务器,当我重新启动将显示路径的服务器,否则它什么都不显示。所以有人可以帮我吗?
答案 0 :(得分:1)
我没有完全理解你的问题,但这里有几点意见。
批处理文件中设置的环境变量(由shell进程执行,cmd.exe
) - 或任何其他类型的进程 - 只能为非常设置>过程。
也就是说,每个进程都有一个特殊的块,当创建该进程时,操作系统可以使用环境变量。
这也意味着当完成设置环境变量的过程时,它的环境块就消失了。
环境变量可以由一个进程继承,该进程由设置该环境变量的进程启动。
这意味着如果您按顺序运行两个批处理脚本,则意味着
第一个cmd.exe
进程被执行,它执行的批处理脚本
设置环境变量;然后这个过程就消失了,它的环境也就消失了。
然后启动另一个cmd.exe
,它继承了主机进程的环境块(写入Go),但正如您所看到的,第一批脚本设置的任何内容都不可用。
有两种方法可以解决问题:
让第一个批处理脚本自行调用第二个脚本。
在这种情况下,第二个cmd.exe
将继承环境变量
由第一个脚本设置,因此将“看到”它们。
请注意,Windows批处理命令语言支持calls
命令通过其路径名调用其他批处理脚本。
使第一个脚本将该变量的值传递给您的主机进程,然后在主机进程中安排第二个cmd.exe
使指定的变量在其环境中具有指示的值。
说,第一个脚本可以执行类似
的操作 echo VARNAME=value
拥有
VARNAME=value
打印到它的标准输出。
您的Go流程可以解析该输出,将其拆分为=
字符,清理不影响像PATH
这样的“有趣”变量,
USERPROFILE
等,然后主持人进程可以
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")
完成的)
它从标准输入流中读取命令并逐个执行 - 直到流关闭(由发送方)。
因此,您可以执行以下操作:
在将cmd.exe
的实例连接到io.Pipe
时开始Stdin
。
首先打开第一个脚本 ,然后通过第一步设置的管道将其铲在正在运行的cmd.exe
上。
不要忘记Flush()
管道。
您可以使用io.Copy()
函数将所有数据从已打开的io.Reader
发送到某些io.Writer
。
让shell实例继续运行。
到时候,请阅读第二个脚本并将其铲在同一个外壳上。
由于shell是相同的,所以第二个脚本的运行就好像它被物理地附加到第一个脚本一样,并且会看到第一个脚本设置的所有变量。