在下一个批处理脚本运行中使用由批处理脚本设置的环境变量

时间:2016-12-30 06:34:02

标签: batch-file go environment-variables windows-scripting

实际上我想运行2个bat脚本,第一个脚本将设置系统变量set NEWPATH="E:/Some",第二个脚本将显示该变量的路径:echo %NEWPATH%。这不是第一次使用同一台服务器,当我重新启动将显示路径的服务器,否则它什么都不显示。所以有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

我没有完全理解你的问题,但这里有几点意见。

一些理论

  • 批处理文件中设置的环境变量(由shell进程执行,cmd.exe) - 或任何其他类型的进程 - 只能为非常设置>过程。

    也就是说,每个进程都有一个特殊的块,当创建该进程时,操作系统可以使用环境变量。

    这也意味着当完成设置环境变量的过程时,它的环境块就消失了。

  • 环境变量可以由一个进程继承,该进程由设置该环境变量的进程启动。

您的情况会发生什么

这意味着如果您按顺序运行两个批处理脚本,则意味着

  1. 第一个cmd.exe进程被执行,它执行的批处理脚本 设置环境变量;然后这个过程就消失了,它的环境也就消失了。

  2. 然后启动另一个cmd.exe,它继承了主机进程的环境块(写入Go),但正如您所看到的,第一批脚本设置的任何内容都不可用。

  3. 你可以做些什么

    有两种方法可以解决问题:

    • 让第一个批处理脚本自行调用第二个脚本。

      在这种情况下,第二个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")完成的) 它从标准输入流中读取命令并逐个执行 - 直到流关闭(由发送方)。

    因此,您可以执行以下操作:

    1. 在将cmd.exe的实例连接到io.Pipe时开始Stdin

    2. 首先打开第一个脚本 ,然后通过第一步设置的管道将其铲在正在运行的cmd.exe上。

      不要忘记Flush()管道。

      您可以使用io.Copy()函数将所有数据从已打开的io.Reader发送到某些io.Writer

    3. 让shell实例继续运行。

    4. 到时候,请阅读第二个脚本并将其铲在同一个外壳上。

    5. 由于shell是相同的,所以第二个脚本的运行就好像它被物理地附加到第一个脚本一样,并且会看到第一个脚本设置的所有变量。