Bash玩转脚本5之Windows上修改环境变量的脚本系统

Posted 小杨在玩iOS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash玩转脚本5之Windows上修改环境变量的脚本系统相关的知识,希望对你有一定的参考价值。

一、前言


我不太喜欢用Window打代码,感觉到处都会被束缚,没有Mac那么行云流水 - 0-

比如今天在Window上开发的时候,遇到了一个问题:

使用新版本的JDGUI时候,提示需要使用JDK7以上的版本,于是乎只能win+PauseBreak呼出控制面板,在高级系统里面去设置JAVA_HOME的值为JDK7的路径。

设置完就感觉很不遍历,假如我有需求需要不断修改Java的版本呢?例如eclipse需要JAVA6,但是JDGUI却需要JAVA7(在Mac上只需要一个bash脚本,修改Java指向的软链接即可),那在Windows上该怎么弄呢?

于是乎,便花了几个小时顺着这个方向,从零开始整一整Window上的脚本环境。

二、目的

从直接需求出发,我想实现的是一个能够修改Java环境变量的脚本。要实现这个需求,实际上需要完成下面几点:

  • 可以在cmd的任何目录直接执行指令
  • 接收参数,动态的修改环境变量的值
  • 重启cmd能立即生效

最后达到的状态便是,win+R呼出cmd

三、Just do it

按照思路一个问题一个问题的来:

1、可以在cmd任何目录直接执行指令

首先想到的便是通过环境变量实现,在环境变量中添加一个值,使得在执行指令的时候,系统能够搜寻到该目录里面的脚本。(其实就类似与Linux和Unix中的profile文件)

添加一个BAT_HOME,指向一个具体的目录,我们之后会把脚本放到该目录。

然后在环境变量PATH中添加%BAT_HOME%

准备工作完成,我们在BAT_HOME 的文件夹里面的新建一个bat文件TestTT.bat进行测试。

TestTT.bat

@echo off
title hello world
:start
echo helloworld
pause

呼出cmd,执行TestTT

这样便有了最初的实现了,方便我们在任何目录位置执行脚本。可以说这一步是非常重要的,因为我们有了自己的脚本体系了,以小见大,以后可以把脚本都放在这个目录,来实现各种各样的功能了。

2、接收参数,动态的修改环境变量的值

在这个实现上,经过了些许思考,好不犹豫的选择了python~~哈哈!理由很简单,bat语法不友好,python在逻辑上更容易修改(当然语言只是工具,具体的实现用自己喜欢就行)

我是用bat脚本调用python脚本实现逻辑控制,在具体修改环境变量的时候,再使用os.system调用bat脚本实现环境变量的修改。(这些bat脚本我都放在了BAT_HOME中)

changePath.bat : 简单的调用python脚本

@echo off
python F:\\PythonProj\\pathChange\\pathChange.py %1 %2

python脚本

# -*- coding: utf-8 -*-
# @auth atanyyang
# @blog http://blog.csdn.net/yang8456211 

import os
import sys

# 这里路径要加一层引号,否则会被截断
JAVA_HOME_6 = '"C:\\Program Files (x86)\\Java\\jdk1.6.0_13"'
JAVA_HOME_7 = '"C:\\Program Files\\Java\\jdk1.7.0_80"'

PYTHON_HOME_2 = '"D:\\Program Files\\Python23"'
PYTHON_HOME_3 = '"D:\\Program Files\\Python35-32"'

def delete(lan):
    if lan == 'java':
        _lan = 'JAVA_HOME'
    elif lan == 'python':
        _lan = 'PYTHON_HOME'
    elif lan == 'test':
        _lan = 'TEST_HOME'
    else:
        return

    os.system('deletepath %s' % _lan)

def add(lan,ver):
    if lan == 'java':
        _lan = 'JAVA_HOME'

        if ver == "6":
            _ver = JAVA_HOME_6
        elif ver == "7":
            _ver = JAVA_HOME_7

    elif lan == 'python':
        _lan = 'PYTHON_HOME'

        if ver == "2":
            _ver = PYTHON_HOME_2
        elif ver == "3":
            _ver = PYTHON_HOME_3
        else:
            return

    elif lan == 'test':
        _lan = 'TEST_HOME'
        _ver = "addnew1"
    else:
        return

    #print ("=========>" , _lan ,"--",_ver)

    os.system('addpath %s %s' % (_lan,_ver))

def main():
    # 检查输入
    if (len(sys.argv) != 3):
        print("argv is error, len is " + len(sys.argv))
        sys.exit(2)

    lan = sys.argv[1]
    version = sys.argv[2]

    if lan not in ['java','python','test']:
        print ("lan is wrong, plz check");
        sys.exit(3)

    if (lan == 'java' and version not in ['6','7']) or  (lan == 'python' and version not in ['2','3']):
        print ("version is wrong, plz check");
        sys.exit(4)

    # 先删除
    delete(lan)

    # 再添加
    add(lan,version)


if __name__ == '__main__':
    main()

这里有一个问题需要注意,耽误了我很大部分的时间,就是在使用os.system调用bat脚本的时候,os.system('addpath %s %s' % (_lan,_ver)),这里传入的_ver路径如果存在空格会被截断!导致环境变量会被修改成C:\\Program,而不是正确的路径值。


经过研究,处理方法有两种:

(第一种是在有空格的路径双引号外,再加多一层单引号)

例如:

JAVA_HOME_6 = '"C:\\Program Files (x86)\\Java\\jdk1.6.0_13"'

在JAVA_HOME_6 字符串外加多一层单引号,就能够正常传递带空格的字符串了~

(第二种是不要使用os.system方法,修改为subprocess.popen)

理论上我应该少用os.system 而改为用subprocess.popen,但是因为subprocess是python2.4以后才有的Api,而我在修改Java环境变量的同时,也有修改python版本的需求,当python切到2.3版本的时候,subprocess便找不到了,因此在这里使用了第一种的方法。

参数已经处理完毕,我们调用bat脚本,来实现环境变量的修改,这里为了简单我选择写了两个脚本一个addpath,一个deletepath,方便以后的复用,在这里我们我们先删除环境变量,再添加环境变量。

deletepath

@echo off
title deletepath
:start
echo begin deletepath %1

set regpath=HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment
set evname=%1
reg delete "%regpath%" /v "%evname%"  /f

echo end deletepath %1

addpath

@echo off
title addpath

echo begin addpath %1 %2

set regpath=HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment
set evname=%1
set thepath=%2
reg add "%regpath%" /v %evname% /d %thepath% /f

:: 如果没有这一句不会立即生效
setx %1 %2 -m 

echo end addpath %1 %2

3、重启cmd能立即生效

最开始写完脚本尝试的时候,发现环境变量并不能立即生效,必须打开环境变量手动点击一次确定才能生效,这里耗费了较多时间去Google这个问题。

最后发现,在脚本里面应该已经看到,如果需要立即生效,需要使用setx %1 %2 -m,这个指令的意思其实就是修改环境变量中%1中的值为%2,使其立即生效。

因此,bat层的脚本也可以通过setx直接实现修改Java的环境变量,只需要简单的修改一下python和bat脚本,在此就不赘述了。

杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。
博文地址:http://blog.csdn.net/yang8456211/article/details/54914505
博客地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商业用途-保持一致”创作公用协议

以上是关于Bash玩转脚本5之Windows上修改环境变量的脚本系统的主要内容,如果未能解决你的问题,请参考以下文章

windows怎么提取bash脚本

玩转Bash脚本:选择结构之case

Bash玩转脚本2之自己的脚本管理工具

Bash玩转脚本1之自己的脚本安装程序

玩转Bash脚本:循环结构之while循环(转)

Bash玩转脚本1之自己的脚本安装程序