我正在尝试通过paramiko exec_command
运行以下命令。当我通过paramiko运行此命令时,与将其粘贴到ssh终端会话中的外壳中时,stdout有所不同(我从python脚本打印了命令,然后将输出直接粘贴到ssh终端中。)
命令是根据其他作业的完成时间将作业提交到LSF队列,但是我不确定我的问题与此有关:
bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script.sh
通过paramiko运行脚本时,这是代码和标准输出: 在:
alljobs=$(cat path/to/job_list.txt | sed '$!{:a;N;s/\n/\) \&\& done\(/;ta}')
echo $alljobs
cmd='bsub -w "done('$alljobs')" < path/to/script1.sh'
echo $cmd
var="$(echo ${cmd}|sh)"
echo $var
var0=$(echo $var | awk -F "[\<\>]" '{print $2}')
echo $var0
var1="$(bsub -w "done($var0)" < path/to/script2.sh)"
echo $var1
echo "this is the end of the script"
退出:
100001) && done(100002) && done(100003
bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script1.sh
this is the end of the script
但是,如果我只是登录ssh会话并粘贴bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script.sh
这是输入/输出:
在:
alljobs=$(cat path/to/job_list.txt | sed '$!{:a;N;s/\n/\) \&\& done\(/;ta}')
echo $alljobs
cmd='bsub -w "done('$alljobs')" < path/to/script1.sh'
echo $cmd
var="$(echo ${cmd}|sh)"
echo $var
var0=$(echo $var | awk -F "[\<\>]" '{print $2}')
echo $var0
var1="$(bsub -w "done($var0)" < path/to/script2.sh)"
echo $var1
echo "this is the end of the script"
退出:
100001) && done(100002) && done(100003
bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script1.sh
Job <111111> is submitted to queue <premium>.
111111
Job <222222> is submitted to queue <premium>.
this is the end of the script
我猜想这是paramiko与交互式会话的问题,但我不确定。
编辑:尝试将get_pty=True
(以及False
)添加到exec_command
,没有任何区别。
编辑#2:在shell中以及从paramiko中打印$ PATH,即使使用get_pty=True
,它们的确也有所不同,当我手动将用户名存储在$ PATH中时,使用的是$ PATH,而在paramiko使用的$ PATH。所以这可能就是问题,现在来看我是否可以对此做任何事情。
编辑#3:This does not sound encouraging,或至少听起来像我可能需要系统管理员的帮助。
编辑#4:我尝试使用ssh.invoke_shell
调用shell脚本并将命令直接写到stdin。尽管确实调用了脚本,但结果是相同的。但是后来我检查了$ PATH,发现我确实在使用与在invoke_shell
下手动登录时相同的$ PATH。所以我也许$ PATH不是问题吗?
我对invoke_shell
的测试使用是这样的:
cmd = "echo $PATH > " + full_path + "/printpath.txt\n"
print(cmd)
channel = ssh.invoke_shell()
stdin = channel.makefile('wb')
stdout = channel.makefile('rb')
stdin.write(cmd)
print(stdout.read())
编辑#5:解决方案!
事实证明,我需要使用多种方法来使其正常工作。一个是使用bash --login
(如@cxw所建议的那样)运行命令,然后我还必须修改命令以使三引号转义内部引号。所以我的工作蟒蛇是:
cmd = "bsub -w \\\"" + jobz + "\\\" < " + exp_path + "/bsubmit2_" + EXPNAME + ".sh"
explicit = 'bash --login -c "' + cmd + '"'
print(explicit)
stdin, stdout, stderr = ssh.exec_command(explicit)