我正在尝试制作一个python脚本,该脚本自动将文件从我的内部驱动器移动到插入的任何USB驱动器。但是,此目标路径是不可预测的,因为我并非每次都使用相同的USB驱动器。使用Raspbian Buster完整版时,到目前为止,我能做的最好的事情就是将其自动挂载到/ media / pi / xxxxx中,其中xxxxxx部分是不可预测的。我正在尝试为此添加脚本帐户。我可以通过以下方式获得驱动器安装点
drives = os.listdir("/media/pi/")
但是我担心有些会因为在被拉出之前没有被卸载而无效(我需要在没有显示器,键盘,VNC或任何用户输入的情况下运行此设备,而不是替换USB驱动器)。因此,我认为我可能需要在if elif elif elif链中进行一系列try catch语句,以确保目标确实是有效的,但是我不知道该如何执行而无需进行硬编码名称中的名称。我知道如何通过一组我不知道的名称进行迭代的唯一方法是
for candidate_drive in drives:
但是我不知道如何使它进入下一个候选驱动器,除非当前驱动器抛出异常。
系统:Raspberry Pi 4,Raspbian buster完整,Python 3.7。
旁注:我也在具有usbmount的Buster lite上进行了尝试,它确实具有可预知的挂载名称,但是我无法安装exfat和ntfs,这是另一篇文章的问题。
更新:我在考虑这件事,也许我需要尝试一下,但else语句中的除外是pas而else是break?我正在尝试。
Update2:我重新考虑了我的问题,也许不是寻找异常以确定何时尝试下一个可能的驱动器,否则我可以寻找成功的传输并中断循环。
import os
import shutil
files_to_send = os.listdir("/home/outgoing_files/")
source_path = "/home/outgoing_files/"
possible_USB_drives = os.listdir("/media/")
for a_possible_drive in possible_USB_drives:
try:
destpath = os.path.join("/media/", a_possible_drive)
for a_file in files_to_send:
shutil.copy(source_path + a_file, destpath)
except:
pass # transfer to possible drive didn't work
else:
break # Stops this entire program bc the transfer worked!
答案 0 :(得分:1)
如果目录的侧面有无数个目录,等等。。。不能使用嵌套的for
cicle。您需要实现一个递归调用函数。如果您在目录中有目录,那么您想查看所有目录,可以使用相同的函数遍历目录列表,反复遍历目录,直到找到文件为止。
让我们看一个例子,您具有这样的路径结构:
path
dir0
dir2
file3
dir1
file2
file0
file1
您现在无法确定要迭代此结构中的al个元素需要多少for
个cicle。您可以在单个目录的所有元素上调用迭代(for
cicle),并对元素内部的元素执行相同的操作。在此结构dirN
中,N
是数字表示目录,而fileN
是文件。
您可以使用os.listdir()
函数来获取目录的内容:
print(os.listdir("path/"))
返回:
['dir0', 'dir1', 'file0.txt', 'file1.txt']
使用此功能和所有目录,您可以获取结构的所有元素。您只需要遍历所有目录。具体来说是目录,因为如果使用文件:
print(os.listdir("path/file0.txt"))
您收到一个错误:
NotADirectoryError: [WinError 267]
但是,请记住,在Python中存在生成器表达式。
字符串工作
如果您有mainpath
,则需要访问其中包含完整字符串引用的目录:"path/dirN"
。您无法直接访问不在.py脚本范围内的文件:
print(os.listdir("dir0/"))
遇到错误
FileNotFoundError: [WinError 3]
因此,您需要始终使用实际路径设置初始主路径的格式,通过这种方式您可以访问结构的所有元素。
过滤
我说过,您可以使用生成器表达式来递归获取结构的目录。让我们看一下功能:
def searchfile(paths: list,search: str):
for path in paths:
print("Actual path: {}".format(path))
contents = os.listdir(path)
print("Contents: {}".format(contents))
dirs = ["{}{}/".format(path,x) for x in contents if os.path.isdir("{}/{}/".format(path,x)) == True]
print("Directories: {} \n".format(dirs))
searchfile(dirs,search)
在此函数中,我们使用os.listdir()
获取实际路径的内容,然后使用生成器表达式对其进行过滤。显然,我们将递归函数调用与实际路径的目录结合使用:searchfile(dirs,search)
该算法可以应用于任何文件结构,因为path
参数是一个列表。因此,您可以迭代包含目录的目录,以及其中包含更多目录的目录。
如果要获取特定文件,可以使用第二个参数search
。您还可以实现条件并获取找到的文件的特定路径:
if search in contents:
print("File found! \n")
print("{}".format(os.path.abspath(search)))
sys.exit()
希望对您有所帮助。