ssh:在终端中运行的javac命令在通过ssh执行时不起作用

lsmd5eda  于 2021-05-30  发布在  Hadoop
关注(0)|答案(2)|浏览(479)

我使用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上的“*”发生了一些事情。

qxsslcnc

qxsslcnc1#

您传递的是参数列表,而不是命令列表。这甚至不是一个准确的论点列表。
如果基础工具需要参数列表,则传递:

['sh', '-c', 'javac -cp /usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/*  remote_hadoop/javasrc/*']

如果需要命令列表:

['javac -cp /usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/*  remote_hadoop/javasrc/*']

如果它需要其他东西——请阅读文档并确定它是什么!
注意,ssh没有提供在运行任意命令时传递文本argv数组的方法;相反,它期望——在协议级别——一个字符串可以由远程shell进行解析。如果你的 self.shell.run 代码在加入给定的参数列表之前进行shell引用,然后将最后一个参数作为文本字符串传递 remote_hadoop/javasrc/* --不像shell那样将其扩展到文件名列表中。
使用 sh -c 表单强制远程shell在其端部执行扩展,假设内容以尚未执行远程扩展的表单形式提供给它。

zpjtge22

zpjtge222#

问题在于 spur 将命令列表生成命令字符串。它接受每个命令标记并用单引号括起来( ["ls", "*.txt"]) 变成 'ls' '*.txt' ). 没有外壳膨胀 * 内引号,所以命令不起作用。
您可以在第323行的spur的ssh.py中看到问题:

def escape_sh(value):
    return "'" + value.replace("'", "'\\''") + "'"

我不使用spur,但它看起来就是不允许你做这样的事情。像spur这样的“简化器”的问题是,如果它们以你不想要的方式简化,你就不能使用它们。

相关问题