使用paramiko与交互式shell调用时,shell脚本的行为有所不同

时间:2019-04-13 10:18:00

标签: bash ssh paramiko lsf

我正在尝试通过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)

0 个答案:

没有答案