在shell/python中传递变量

ezykj2lf  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(407)

我使用一个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'
0ejtzxu1

0ejtzxu11#

我猜您正在对路径进行url编码,以便将其正确地传递给hadoop,但这样做基本上是对shell隐藏它。确实没有与通配符匹配的文件 /tmp/BC10%5EDummy-Segment* 哪里 % etc是文字字符。
尝试从python处理glob。有了这个,你也可以摆脱那个讨厌的家伙 shell=True ; 通过这种更改,最终将命令作为字符串列表传递是正确和有用的(从来不是单个空格分隔的字符串列表,并且 shell=True ,根本不传递列表)。另请注意切换到 check_call 因此,我们捕获错误,如果复制失败,就不会删除源文件(另请参见https://stackoverflow.com/a/51950538/874188 其他理由。)

import glob
import subprocess
import os
from urllib import quote_plus

filePath = "/tmp"
keyword = "BC10^Dummy-Segment"

wildcard = os.path.join(filePath, '{0}*'.format(keyword))
files = [quote_plus(x) for x in  glob.glob(wildcard)]
subprocess.check_call(["hadoop", "fs", "-copyFromLocal"] + files + ["/user/app"])
subprocess.check_call(["hadoop", "fs", "-rm"] + files)

这不会遍历子目录;但你也不想 os.walk() 如果它在子目录中找到文件,就做任何实际有用的事情。如果你真的想这样做,请更详细地解释脚本应该做什么。

相关问题