我使用python代码在使用ssh的linux(cloudera)机器上运行hadoop程序。
我在将java文件编译成类文件时遇到了一些问题。当我执行命令时: javac -cp /usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/* remote_hadoop/javasrc/*
从linux终端,所有文件都被成功编译。
当我通过python ssh客户端执行同一命令时,我收到一个“invalid flag”错误:
spur.results.runprocesserror:返回代码:2输出:b''stderr输出:b'javac:无效标志:remote\u hadoop/javasrc\n用法:javac\nuse-有关可能选项列表的帮助\n'
python代码:
list_of_commands = ["javac", "-cp", r"/usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/*", input_folder + r"/*"]
print ' '.join(list_of_commands)
self.shell.run(list_of_commands)
命令正确呈现,因为打印的是 javac -cp /usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/* remote_hadoop/javasrc/*
.
更新:这很奇怪。我可以通过ssh一次编译一个文件,但不能全部编译。似乎ssh上的“*”发生了一些事情。
2条答案
按热度按时间qxsslcnc1#
您传递的是参数列表,而不是命令列表。这甚至不是一个准确的论点列表。
如果基础工具需要参数列表,则传递:
如果需要命令列表:
如果它需要其他东西——请阅读文档并确定它是什么!
注意,ssh没有提供在运行任意命令时传递文本argv数组的方法;相反,它期望——在协议级别——一个字符串可以由远程shell进行解析。如果你的
self.shell.run
代码在加入给定的参数列表之前进行shell引用,然后将最后一个参数作为文本字符串传递remote_hadoop/javasrc/*
--不像shell那样将其扩展到文件名列表中。使用
sh -c
表单强制远程shell在其端部执行扩展,假设内容以尚未执行远程扩展的表单形式提供给它。zpjtge222#
问题在于
spur
将命令列表生成命令字符串。它接受每个命令标记并用单引号括起来(["ls", "*.txt"])
变成'ls' '*.txt'
). 没有外壳膨胀*
内引号,所以命令不起作用。您可以在第323行的spur的ssh.py中看到问题:
我不使用spur,但它看起来就是不允许你做这样的事情。像spur这样的“简化器”的问题是,如果它们以你不想要的方式简化,你就不能使用它们。