解决SublimeText安装Package的权限错误

     0评论

长久以来发现SublimeText安装Package会有权限错误,必须以管理员身份重启才能安装成功,却不知原因,因为平时并不经常安装新包,也就忍了。最近频繁安装新包,趁机一鼓作气将问题解决了,原来是环境变量的问题。

先说结论,如果你遇到了类似PermissionError: [WinError 5] 拒绝访问.: 'c:\windows\temp\tmp4lweqh\working'的错误,去看一下用户环境变量TMP/TEMP的当前值是%USERPROFILE%\AppData\Local\TEMP还是%SystemRoot%\TEMP,若是后者或其它非用户目录,将其改为前者,然后重启系统试试,大概率可以解决。

下面是Debug除错的过程:

错误详情

Exception in thread Thread-188: Traceback (most recent call last): File "./python3.3/threading.py", line 901, in _bootstrap_inner File "D:\PortableSoftware\SublimeText3\Data\Installed Packages\Package Control.sublime-package\package_control/package_installer.py", line 202, in run self.result = self.manager.install_package(self.package) File "D:\PortableSoftware\SublimeText3\Data\Installed Packages\Package Control.sublime-package\package_control/package_manager.py", line 1288, in install_package os.chdir(package_dir) PermissionError: [WinError 5] Access denied.: 'c:\windows\temp\tmp4lweqh\working'

定位错误

看日志,错误是Package Control这个包管理器抛出的,具体问题出在Data\Installed Packages\Package Control.sublime-package\package_control/package_manager.py的第1288行:它无法切换到一个特定目录。打开包中的此文件,定位到第1288行,追踪package_dir这个变量的由来,可以发现根源是在python的tempfile这个包,它在特定目录创建了一个临时工作目录,将目录路径赋值给package_dir,然后在试图切换到此目录时发生了错误。

在控制台运行相关代码,可以重现此错误:

Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tempfile >>> tmp_dir = tempfile.mkdtemp(u'') >>> print(tmp_dir) c:\windows\temp\tmptagljs >>> import os >>> tmp_working_dir = os.path.join(tmp_dir, 'working') >>> os.mkdir(tmp_working_dir) >>> package_dir = tmp_working_dir >>> os.chdir(package_dir) Traceback (most recent call last): File "", line 1, in WindowsError: [Error 5] : u'c:\\windows\\temp\\tmptagljs\\working' >>> os.chdir(tmp_dir) Traceback (most recent call last): File "", line 1, in WindowsError: [Error 5] : u'c:\\windows\\temp\\tmptagljs' >>> exit()

虽然SublimeText使用的是内置的python和tempfile包,但道理是相通的。显然,问题的起点在于运行tempfile.mkdtemp(u'')时,tempfile根据特定原则选择的工作目录有问题。搜索tempfile的文档,可以发现其选定起始工作目录的原则为:

When set to a value other than None, this variable defines the
default value for the dir argument to all the functions defined in this
module.

If tempdir is unset or None at any call to any of the above
functions, Python searches a standard list of directories and sets
tempdir to the first one which the calling user can create files in.
The list is:

  1. The directory named by the TMPDIR environment variable.
  2. The directory named by the TEMP environment variable.
  3. The directory named by the TMP environment variable.
  4. A platform-specific location:
    • On RiscOS, the directory named by the Wimp$ScrapDir environment
      variable.
    • On Windows, the directories C:\TEMP, C:\TMP,
      \TEMP, and \TMP, in that order.
    • On all other platforms, the directories /tmp, /var/tmp, and
      /usr/tmp, in that order.
  5. As a last resort, the current working directory.

也就是如果没有定义tempdir这个变量,模块会从一个优先顺序列表中选择可用的作为tempdir的值,因为Package Control调用这个模块时并没有设定tempdir,于是TEMP或者TMP这样的环境变量就被使用了。当以登陆用户的身份运行SublimeText,而此用户对TEMPTMP等被优先选用的环境变量指向的路径无权限,就可能出现上面的错误了。我的这两个环境变量不知为何被设置为了%SystemRoot%\TEMP,而其值本来应该是%USERPROFILE%\AppData\Local\TEMP

验证思路

在控制台设定TMP/TEMP环境变量设为当前用户可读写的路径后,os.chdir不报错了。

[email protected] MSYS ~ $ tmp=$USERPROFILE\\AppData\\Local\\TEMP [email protected] MSYS ~ $ temp=$USERPROFILE\\AppData\\Local\\TEMP [email protected] MSYS ~ $ wpy Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tempfile >>> tmp_dir = tempfile.mkdtemp(u'') >>> print(tmp_dir) c:\users\sf\appdata\local\temp\tmpkqwbj1 >>> import os >>> tmp_working_dir = os.path.join(tmp_dir, 'working') >>> os.mkdir(tmp_working_dir) >>> package_dir = tmp_working_dir >>> os.chdir(package_dir) >>> exit()

解决问题

明白了原理,就发现只要保证tempdir被调用时,指向一个当前用户有足够权限的路径即可。根据上述引用的原则,有以下方法可选:

  • TMPDIR/TEMP/TMP环境变量设为当前用户可读写的路径,通常为%USERPROFILE%\AppData\Local\TEMP
  • 删除上述环境变量,提供当前用户可读写的C:\TEMP 或者 C:\TMP目录
  • 删除上述环境变量,以及C:\TEMP 或者 C:\TMP目录,在当前工作目录下建立TEMP 或者 TMP文件夹

疑惑

  • 实际操作中发现,即使已成功设定了TEMP环境变量,并确保其已生效,错误还是会发生,重启系统后问题才真正解决。
  • 为什么错误发生在切换目录,也就是os.chdir这一步,而不是在os.mkdir时就抛出错误。

其它

实际排错的过程不是一步到位的,我在论坛发帖后收到一份回复,指出可能是环境变量的问题,但设定环境变量后问题依旧,过了一天电脑重启后想起来再试试,发现问题解决了。这里分享下回复者的分析思路及其提供的线索:

I’m not a Windows guru, but I think the temp folder inside of the Windows folder is supposed to be for system use and your user temp folder should be stored somewhere under AppData\Local in your home directory (i.e. every user should have their own unique temp folder).
If that’s the case, perhaps it’s going pear shaped because it’s picking a temp folder that it doesn’t have access to.
Do you have any environment variables set up that are changing the temp directory to somewhere else?

参考资料

-- EOF --

本文最后修改于1年前 (2019-05-07)

差评不太行一般挺好非常不错 (No Ratings Yet)
读取中...
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址