我使用一个python脚本,其中我使用shell命令从本地复制到hdfs。
import os
import logging
import subprocess
filePath = "/tmp"
keyword = "BC10^Dummy-Segment"
for root, dirs, files in os.walk(filePath):
for file in files:
if keyword in file:
subprocess.call(["hadoop fs -copyFromLocal /tmp/BC10%5EDummy-Segment* /user/app"], shell=True)
subprocess.call(["hadoop fs -rm /tmp/BC10%5EDummy-Segment*"], shell=True)
我看到这个错误:
copyFromLocal: `/tmp/BC10^Dummy-Segment*': No such file or directory
rm: `/tmp/BC10^Dummy-Segment_2019': No such file or directory
更新代码:
import glob
import subprocess
import os
from urllib import urlencode, quote_plus
filePath = "/tmp"
keyword = "BC10^Dummy-Segment"
wildcard = os.path.join(filePath, '{0}*'.format(keyword))
print(wildcard)
files = [urlencode(x, quote_via=quote_plus) for x in glob.glob(wildcard)]
subprocess.check_call(["hadoop", "fs", "-copyFromLocal"] + files + ["/user/app"])
# subprocess.check_call(["hadoop", "fs", "-rm"] + files)
运行时看到错误:
Traceback (most recent call last):
File "ming.py", line 11, in <module>
files = [urlencode(x, quote_via=quote_plus) for x in glob.glob(wildcard)]
TypeError: urlencode() got an unexpected keyword argument 'quote_via'
1条答案
按热度按时间0ejtzxu11#
我猜您正在对路径进行url编码,以便将其正确地传递给hadoop,但这样做基本上是对shell隐藏它。确实没有与通配符匹配的文件
/tmp/BC10%5EDummy-Segment*
哪里%
etc是文字字符。尝试从python处理glob。有了这个,你也可以摆脱那个讨厌的家伙
shell=True
; 通过这种更改,最终将命令作为字符串列表传递是正确和有用的(从来不是单个空格分隔的字符串列表,并且shell=True
,根本不传递列表)。另请注意切换到check_call
因此,我们捕获错误,如果复制失败,就不会删除源文件(另请参见https://stackoverflow.com/a/51950538/874188 其他理由。)这不会遍历子目录;但你也不想
os.walk()
如果它在子目录中找到文件,就做任何实际有用的事情。如果你真的想这样做,请更详细地解释脚本应该做什么。