如何从Python脚本中可靠地检查刚创建的目录是否存在?

huangapple go评论71阅读模式
英文:

How to reliably check from Python script code if just created directory exist?

问题

以下是代码部分的中文翻译:

当我在一个系统上运行以下代码,该系统上不存在/AnewDir目录,然后在代码退出后系统上就会有一个新目录:

from subprocess import Popen, PIPE
from os.path import isdir
from time import sleep
from os import system

sudoShCmd = Popen(["sudo", "-S", "mkdir", "/AnewDir"], stdin=PIPE)
sudoShCmd.stdin.write(b'在这里输入您的ROOT密码') # <<< ###

sleep(1); print()

system("if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi")
print(f'{isdir("/AnewDir")=}')

sleep(3); print()

system("if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi")
print(f'{isdir("/AnewDir")=}')

但是,用于检查目录存在与否的部分未能提供正确的状态报告,即目录不存在(但您可以从控制台或文件管理器中检查到目录存在)。即使等待3秒以获取正确的响应,也不能获得目录是否存在的正确答案。

是否有一种可靠的方式从代码中创建目录来检查目录是否实际创建了?

或者上面的问题只是由于完全混乱而导致的?我是否在思考发生的事情时漏掉了某些东西?

Constantin Hong提供的答案显示了一种更改目录存在性检查之前的代码以便提供正确结果的方法。这表明,预备代码在某种程度上导致了问题,但是...要使这些检查正常工作,无需更改代码。只需在创建/删除目录的脚本退出后从另一个脚本中运行它们即可...

所提供的答案是否意味着无法从创建它的相同代码中可靠地检查目录的存在

英文:

When I am running following code with a on a system not existing /AnewDir directory then after the code exits there is a new directory on the system:

from subprocess import Popen, PIPE
from os.path import isdir
from time import sleep
from os import system

#v--- (Miracle-SWITCH) NEW LINE / BACKSPACE  
#&quot;&quot;&quot; Move cursor after the beginning  #  but before the triple quotes.  
#^-- Press Return to switch to execution of the code part removing the 
# directory. Then press Backspace to switch back to execution of the 
# leading code block (miracle-SWITCH). 
sudoShCmd = Popen([&quot;sudo&quot;, &quot;-S&quot;, &quot;mkdir&quot;, &quot;/AnewDir&quot;], stdin=PIPE) 
sudoShCmd.stdin.write(b&#39;PUT YOUR ROOT PASSWORD HERE&#39;) # &lt;&lt;&lt; ###

sleep(1); print()

system(&quot;if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi&quot;)
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)

sleep(3); print()

system(&quot;if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi&quot;)
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)

&quot;&quot;&quot;
sudoShCmd = Popen([&quot;sudo&quot;, &quot;-S&quot;, &quot;rmdir&quot;, &quot;/AnewDir&quot;], stdin=PIPE) 
sudoShCmd.stdin.write(b&#39;PUT YOUR ROOT PASSWORD HERE&#39;) # &lt;&lt;&lt; ###
#sleep(1); print()
system(&quot;if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi&quot;)
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)
#&quot;&quot;&quot;

but the checks for the existence of the directory fail to provide the proper status reporting that the directory isn't there (but you can check from the console of with a File Manager that the directory is there). It doesn't help to pause for 3 seconds in order to get the proper response to the question if the directory exist.

Is there a way to reliably check from within the code creating the directory if the directory was actually created?

Or is the above question only the result of total confusion? Am I missing something in my way of thinking what is happening there?

The answer provided by Constantin Hong shows a way to change the code preceding the checks for the directory existence so that the checks deliver the proper result. This shows that the preliminary code somehow causes the problem, but ... to make these checks work properly isn't necessary to change the code. It would be sufficient to run them from another script after the exit of the script creating/deleting the directory ...

Does the provided answer imply that there is no way to reliably check for existence of a directory in the same code which creates it?

答案1

得分: 1

以下是您要求的翻译部分:

sudoShCmd = Popen(["sudo", "-S", "mkdir", "/AnewDir"], stdin=PIPE) 
sudoShCmd.stdin.write(b'PUT YOUR ROOT PASSWORD HERE') # <<< ###

是否有一种可靠的方法可以从代码内部检查目录是否实际创建了?

是的。isdir() 函数是一种可靠的检查目录存在性的方法。

这是我的建议。

交互模式 @Aniket Inge 的 想法

password = input("PUT YOUR ROOT PASSWORD HERE")
sudoShCmd = system('echo {password} | sudo -S mkdir /AnewDir 2>/dev/null'.format(password=password))

非交互模式

password = 'yourpassword'
sudoShCmd = system('echo {password} | sudo -S mkdir /AnewDir 2>/dev/null'.format(password=password))

非交互模式与 Popen

from subprocess import Popen, PIPE, DEVNULL
password = Popen(["echo", "YOURPASSWORD"], stdout=PIPE) 
sudoShCmd = Popen(["sudo", "-S", "mkdir", "/AnewDir"], stdin=password.stdout, stderr=DEVNULL) 
sudoShCmd.communicate()

结果

isThere
isdir("/AnewDir")=True

isThere
isdir("/AnewDir")=True

交互模式的代码

from subprocess import Popen, PIPE
from os.path import isdir
from time import sleep
from os import system

password = input("PUT YOUR ROOT PASSWORD HERE")
sudoShCmd = system('echo {password} | sudo -S mkdir /AnewDir 2>/dev/null'.format(password=password)) 
sleep(1); print()

system("if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi")
print(f'{isdir("/AnewDir")=}')

sleep(3); print()

system("if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi")
print(f'{isdir("/AnewDir")=}')
英文:

Your code is good except for these.

sudoShCmd = Popen([&quot;sudo&quot;, &quot;-S&quot;, &quot;mkdir&quot;, &quot;/AnewDir&quot;], stdin=PIPE) 
sudoShCmd.stdin.write(b&#39;PUT YOUR ROOT PASSWORD HERE&#39;) # &lt;&lt;&lt; ###

> Is there a way to reliably check from within the code creating the directory if the directory was actually created?

Yes. isdir() function is a reliable way to check the existence of the directory.

This is my suggestion.

Interactive mode @Aniket Inge's idea

password = input(&quot;PUT YOUR ROOT PASSWORD HERE&quot;)
sudoShCmd = system(&#39;echo {password} | sudo -S mkdir /AnewDir 2&gt;/dev/null&#39;.format(password=password))

Non-interactive mode

password = &#39;yourpassword&#39;
sudoShCmd = system(&#39;echo {password} | sudo -S mkdir /AnewDir 2&gt;/dev/null&#39;.format(password=password))

Non-interactive mode with Popen

from subprocess import Popen, PIPE, DEVNULL
password = Popen([&quot;echo&quot;, &quot;YOURPASSWORD&quot;], stdout=PIPE) 
sudoShCmd = Popen([&quot;sudo&quot;, &quot;-S&quot;, &quot;mkdir&quot;, &quot;/AnewDir&quot;], stdin=password.stdout, stderr=DEVNULL) 
sudoShCmd.communicate()

The result


isThere
isdir(&quot;/AnewDir&quot;)=True

isThere
isdir(&quot;/AnewDir&quot;)=True

The interactive mode code

from subprocess import Popen, PIPE
from os.path import isdir
from time import sleep
from os import system

password = input(&quot;PUT YOUR ROOT PASSWORD HERE&quot;)
sudoShCmd = system(&#39;echo {password} | sudo -S mkdir /AnewDir 2&gt;/dev/null&#39;.format(password=password)) 
sleep(1); print()

system(&quot;if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi&quot;)
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)

sleep(3); print()

system(&quot;if [ -x /AnewDir ]; then echo isThere; else echo isNotThere; fi&quot;)
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)

答案2

得分: 0

你认为检查已创建目录的存在性的结果错误是基于错误的假设,即在检查时目录已存在,但实际并非如此。检查提供了正确的结果。在检查时,目录尚未创建。

您可以自己验证,增加命令之间的间隔时间,以查看目录不会在等待很长时间后创建。它将在脚本退出并刷新数据流时的最后阶段创建,这将导致 spawn Popen() 变为活动状态并在执行检查目录存在性的代码行之后创建目录。

您以顺序执行代码行的方式思考,但使用 Popen() 方法会生成另一行代码执行,它更多或多少地自行执行,因此从现在开始执行代码行的顺序可能会倒转,并导致您观察到的结果。

请查看以下问题的答案和评论以获取更多详细信息:

https://stackoverflow.com/questions/75690982/why-does-the-python-code-creating-a-directory-get-executed-after-the-code-at-the

下面的代码显示了检查正确的目录状态,因为目录的创建不与脚本的主执行路径并行运行:

from subprocess import run
from os.path import isdir
run('echo YOUR_ROOT_PASSWORD | sudo -S mkdir /AnewDir 2>/dev/null', shell=True) 
print(f'{isdir("/AnewDir")=}')

"技巧" 是使用 "shell=True" 选项,同时通过管道直接在命令行中提供密码。

英文:

Your opinion that the check of existence of the created directory delivers a wrong result is based on an erroneous assumption that at the time of the check the directory already exists, but it doesn't. The check delivers the right result. At the time of the check the directory is not yet created.

You can check it out yourself increasing the time of the gap between the commands to see that the directory is not created within the looong time of waiting. It will be created at the very end when the script is in the process of exiting flushing data streams what then causes the spawn Popen() to become active and create the directory AFTER the code lines checking for the directory existence are executed.

You think in terms of sequential execution of lines of code, but with the Popen() method you spawn another line of code execution which acts more or less on its own, so it is possible that the order in which from now on the lines are executed can get reversed and results in what you have observed.

Check out the answers and comments to the question:
https://stackoverflow.com/questions/75690982/why-does-the-python-code-creating-a-directory-get-executed-after-the-code-at-the
for more details.

Below code where the checks show the proper directory status because the creation of the directory does not run parallel to the main execution path of the script:

from subprocess import run
from os.path import isdir
run(&#39;echo YOUR_ROOT_PASSWORD | sudo -S mkdir /AnewDir 2&gt;/dev/null&#39;, shell=True) 
print(f&#39;{isdir(&quot;/AnewDir&quot;)=}&#39;)

The "trick" is to use the option "shell=True" coupled with providing the password via a PIPE directly in the command line.

huangapple
  • 本文由 发表于 2023年3月10日 00:30:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687458.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定