Windows 下Git Bash的目录转换

admin 2025年4月18日09:30:40评论2 views字数 3895阅读12分59秒阅读模式
在Windows下使用Git带的Bash环境,在处理C盘、D盘这种路径时,会涉及到路径转换。
比如 C: 会映射成 /c ,D: 会映射成 /d,通过 df 命令也可以看到这种映射关系。
Windows 下Git Bash的目录转换
这种映射关系一直存在,也没有对我造成太多困扰。直到我在Git Bash环境下编写并发执行 rsync 的脚本时发现,给 python 传参无论怎么传都不对。初版脚本如下:
import argparseimport osfrom concurrent.futures import ThreadPoolExecutorimport subprocessimport sysimport platform# 在文件开头添加平台检测IS_WINDOWS = platform.system() == 'Windows'RSYNC_PATH = '/usr/bin/rsync' if not IS_WINDOWS else 'rsync.exe'def change_default_encoding():    '''判断是否在 windows git-bash 下运行,是则使用 utf-8 编码'''    if platform.system() == 'Windows':        terminal = os.environ.get('TERM')        if terminal and 'xterm' in terminal:            sys.stdout.reconfigure(encoding='utf-8')def read_backup_list(file_path):    """读取备份目录列表文件,过滤空行和注释"""    directories = []    with open(file_path, 'r'as f:        for line in f:            line = line.strip()            if line and not line.startswith('#'):                directories.append(line)    return directoriesdef run_rsync(src_dir, target_root):    """执行rsync备份(终极路径保留版)"""    try:        # 保留原始路径结构        src = src_dir.rstrip('/') + '/'        dst = target_root.rstrip('/') + '/'        cmd = [            RSYNC_PATH,            '-avhn',            src,            dst        ]        print(cmd, flush=True)        # Windows特殊处理        if IS_WINDOWS:            cmd.insert(1'-rt')  # 替换归档模式参数        # 执行原始命令        subprocess.run(            cmd,            check=True,            shell=IS_WINDOWS,            stdout=subprocess.DEVNULL,            stderr=subprocess.PIPE        )        return True    except subprocess.CalledProcessError as e:        print(f"Failed: {e.stderr.decode().strip()}")        return Falsedef main():    parser = argparse.ArgumentParser(        description='Parallel rsync backup tool',        formatter_class=argparse.ArgumentDefaultsHelpFormatter    )    parser.add_argument(        '-l''--list',        required=True,        help='Path to file containing directory list to backup'    )    parser.add_argument(        '-t''--target',        required=True,        help='Root directory for backups'    )    parser.add_argument(        '-j''--jobs',        type=int,        default=4,        help='Number of parallel jobs'    )    args = parser.parse_args()    # 读取备份目录列表    try:        directories = read_backup_list(args.list)        print(f"📄 Found {len(directories)} directories to backup")    except Exception as e:        print(f"🚨 Error reading list file: {str(e)}")        return    # 创建线程池执行任务    with ThreadPoolExecutor(max_workers=args.jobs) as executor:        futures = []        for idx, src_dir in enumerate(directories, 1):            print(f"🔄 Queueing ({idx}/{len(directories)}): {src_dir}")            futures.append(executor.submit(run_rsync, src_dir, args.target))        # 等待所有任务完成        success = 0        for future in futures:            if future.result():                success += 1        print(f"n📊 Backup complete! Success: {success}/{len(directories)}")if __name__ == '__main__':    change_default_encoding()    main()
脚本逻辑是通过一个目录列表并行执行 rsync,同步的源目录来源于目录列表中的内容,目标目录通过传参获得。
bash$ python sync.py -husage: sync.py [-h] -l LIST -t TARGET [-j JOBS]Parallel rsync backup tooloptions:  -h, --help            show this help message and exit  -l LIST, --list LIST  Path to file containing directory list to backup                        (defaultNone)  -t TARGET, --target TARGET                        Root directory for backups (defaultNone)  -j JOBS, --jobs JOBS  Number of parallel jobs (default: 4)
Windows 下Git Bash的目录转换
其中目录列表中的路径如下:
Windows 下Git Bash的目录转换
当使用 -t 传目标目录时,脚本中的路径会被自动转换。比如传参为 /d/test1
python sync.py -l file.list -t /d/test1/
通过打印目标参数,实际输出为:
Windows 下Git Bash的目录转换
其中 /d/test1/ 被自动转换成了 D:/test1/
这个转换过程是什么时候发生的,以及是谁进行转换的?为了搞清楚,写了一个测试脚本:
bash$ cat test2.pyimport argparseparser = argparse.ArgumentParser()parser.add_argument("--path")  # 默认 type=strargs = parser.parse_args()print(f"Raw path: {args.path}")import sysprint(sys.argv)
简化了其它内容,只保留了传参部分。测试到底是 argparse 模块处理错了,还是系统的 sys.argv 本身就是错的。
执行:
python test2.py --path /d/test1
输出如下:
Windows 下Git Bash的目录转换
通过输出内容判断并不是 argparse 模块的问题,传给 sys.argv 的目录已经是转换后的路径了。测试证明目录转换过程不是由 python 程序处理的,那么就只剩下一种可能,转换过程发生在传参前。
目录转换是由 windows 版的 Bash 程序完成的,当传 /d/test1 时,Bash 程序对参数进行了转换,将其转换成了 D:test1 。
如何避免目录自动转换?可以通过设置环境变量来控制是否自动对目录进行转换。
当环境变量 MSYS_NO_PATHCONV 不为空时,Bash 程序不会自动对目录进行转换。
export MSYS_NO_PATHCONV=1
Windows 下Git Bash的目录转换
此时传参保持了所见即所得的一致性。
如何还原到系统的原始状态?可以通过销毁环境变量还原系统初始设置。
unset MSYS_NO_PATHCONV
Windows 下Git Bash的目录转换
全文完。

原文始发于微信公众号(生有可恋):Windows 下Git Bash的目录转换

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月18日09:30:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Windows 下Git Bash的目录转换http://cn-sec.com/archives/3972629.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息