SSH:在终端上工作的javac命令在通过SSH执行时不起作用

时间:2014-12-19 16:40:45

标签: python hadoop ssh javac cloudera

我正在使用Python代码在Linux(Cloudera)计算机上使用SSH运行Hadoop程序。

我在将java文件编译为类文件时遇到了一些麻烦。当我执行命令时: 来自Linux终端的javac -cp /usr/lib/hadoop/*:/usr/lib/hadoop/client-0.20/* remote_hadoop/javasrc/*所有文件都已成功编译。

当我通过我的Python SSH客户端执行相同的命令时,我收到一个“无效标志”错误:

spur.results.RunProcessError:返回代码:2 输出:b'' stderr输出:b'javac:invalid flag:remote_hadoop / javasrc \ nUsage:javac \ nuse -help,列出可能的选项\ 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 个答案:

答案 0 :(得分:1)

您传递的是参数列表,而不是命令列表。它甚至不是准确的参数列表。

如果你的底层工具需要一个参数列表,那么传递:

['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在其末尾执行扩展,假设已经以不执行远程扩展的形式向其提供内容。

答案 1 :(得分:1)

问题是spur将命令列表构建为命令字符串的方式。它接受每个命令令牌并将其用单引号括起来(["ls", "*.txt"])变为'ls' '*.txt')。引号内没有*的shell扩展,因此该命令不起作用。

你可以在323行的ssh.py中看到问题:

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

我不使用spur,但看起来它只是不允许你做这样的事情。像“马刺”这样的“简化器”的问题在于,如果它们以您不想要的方式简化,则无法使用它们。