作者:金豪情圣 | 来源:互联网 | 2023-08-08 14:11
我将tempfile.TemporaryDirectory
类用作上下文管理器。默认情况下,它应使用/tmp
文件夹。我尝试使用默认值,也尝试强制使用/tmp
文件夹。它会在调用者脚本所在的位置创建临时文件夹。
设置:
- Red Hat 7 Linux
- Python 3.6.6
- 该脚本是从詹金斯调用的
代码:
import tempfile
import os
print(os.path.dirname(__file__))
TMP_DIR_PREFIX = "my_test_"
with tempfile.TemporaryDirectory(prefix=TMP_DIR_PREFIX,dir="/tmp") as tmp_dir:
print(tmp_dir)
输出:
>>> python3 /home/my_home/test.py
home/my_home
home/my_home/my_test_m1vljq2h
我的问题:
我已经阅读了相关的官方文档以及tempfile
模块的实现,但是我没有找到任何可能导致此类问题的相关代码部分。
注意::如果可能的话,我不想继承和更改此模块的许多元素,但是我愿意接受。
编辑:
完成追溯(从运行Jenkins):
File "/my_path/python/3.6.0/lib/python3.6/threading.py",line 916,in _bootstrap_inner
self.run()
File "/my_path/python/3.6.0/lib/python3.6/threading.py",line 864,in run
self._target(*self._args,**self._kwargs)
File "/home/my_home/copy_to_location.py",line 143,in upload_files
with tempfile.TemporaryDirectory(prefix=TMP_DIR_PREFIX,dir="/tmp") as tmp_dir:
File "/my_path/python/3.6.0/lib/python3.6/tempfile.py",line 790,in __init__
self.name = mkdtemp(suffix,prefix,dir)
File "/my_path/python/3.6.0/lib/python3.6/tempfile.py",line 368,in mkdtemp
_os.mkdir(file,0o700)
PermissionError: [Errno 13] Permission denied: '/home/my_home/my_test_q1pldmf2'
EDIT2:
我无法在本地复制它。这个问题只会在詹金斯不断发生!
EDIT3:
添加的行:
logging.info(tempfile._sanitize_params("my_test_",None,None))
Jenkins的输出:
2019-11-08 15:09:26 [Thread-1] [INFO] ('my_test_','','/tmp',)
换行:
logging.info(tempfile._sanitize_params("my_test_","/tmp"))
在詹金斯中添加:
2019-11-08 15:13:46 [Thread-1] [INFO] ('my_test_',)
tempfile.TemporaryDirectory()
对象使用tempfile.mkdtemp()
根据传入的参数创建临时目录。如果您不给它{{1 }}参数。
如果您传递的是dir
和 still ,但看不到在dir='/tmp'
中创建的目录,则有两种可能性:
- 您的
/tmp
值不是您认为的,而是以prefix
开头
- 系统上的
/
模块 已被更改,并且不再具有与tempfile.gettempdir()
相同的方式。这些更改可能是在磁盘上进行的,也可能是通过其他Python代码动态更改了行为。
正常的行为是tempfile
函数调用名为standard library version distributed with Python 3.6.0的内部函数,如果设置,则返回mkdtemp()
不变,否则返回dir
的值:
gettempdir()
>>> import tempfile
>>> tempfile._sanitize_params('my_test_',None,'/tmp')
('my_test_','','/tmp',)
>>> tempfile._sanitize_params('my_test_',None)
('my_test_',)
>>> tempfile.gettempdir()
'/tmp'
然后使用该调用的结果(返回更新的mkdtemp()
,prefix
,suffix
和dir
或bytes
类型)和随机字符串一起为您创建一个新目录。
这可能导致您没有正确排除str
值确实是您认为的那样。 prefix
函数使用:
mkdtemp()
通过前缀,候选值os.path.join(dir,prefix + name + suffix)
(随机值)和后缀(您的情况下为空字符串)的连接来加入dir
路径。但是请注意,_sanitize_params()
将丢弃以name
开头的参数之前的所有路径元素:
/
因此,您看到的行为也可以由以斜杠开头的前缀来解释,所以:
>>> import os.path
>>> os.path.join("/foo","bar")
'/foo/bar'
>>> os.path.join("/foo","/bar")
'/bar'
将立即产生相同的结果:
TMP_DIR_PREFIX = "/home/my_home/my_test_"
这以前是作为os.path.join()
function报告给Python项目的。
您可以在詹金斯(Jenkins)工作中平凡地包含两个测试,以排除这些选项。确保记录>>> TMP_DIR_PREFIX = "/home/my_home/my_test_"
>>> tempfile.mkdtemp(prefix=TMP_DIR_PREFIX,dir="/tmp")
Traceback (most recent call last):
File "",line 1,in
File "/.../lib/python3.6/tempfile.py",line 368,in mkdtemp
_os.mkdir(file,0o700)
PermissionError: [Errno 13] Permission denied: '/home/my_home/my_test_v4cqpamm'
值以及TMP_DIR_PREFIX
返回的值。
如果任何一个都不在您的系统上产生预期的输出,那么您知道您需要专注于寻找; tempfile._sanitize_params(TMP_DIR_PREFIX,'/tmp')
模块的行为已更改,或者您假设tempfile
的值不正确。
您可以使用以下shell命令检查本地副本是否与发布版本不同:
TMP_DIR_PREFIX
或者您可以计算文件的校验和:
$ diff -u \
> <(curl -s https://raw.githubusercontent.com/python/cpython/v3.6.0/Lib/tempfile.py) \
> /my_path/python/3.6.0/lib/python3.6/tempfile.py
并将该校验和值与已发布文件的校验和值进行比较:
import hashlib
with open(tempfile.__file__,'rb') as file_to_hash:
tempfile_checksum = hashlib.sha1(file_to_hash.read()).hexdigest()
如果仍然无法执行任何操作,则可以通过调试器逐步完成调用,也可以查看所涉及函数的$ curl -s https://raw.githubusercontent.com/python/cpython/v3.6.0/Lib/tempfile.py | \
> sha1sum
38ad01ccc5972e193e1b96a1de8b7ba1bd8d289d -
属性。例如。例如,如果__module__
是动态更改的(猴子修补),则_sanitize_params()
将不会设置为tempfile._sanitize_params.__module__
。但是,请注意,您的回溯已经显示'tempfile'
和TemporaryDirectory.__init__
均来自正确的文件,并且可见的两行的行号与发布的源中的行号相匹配。