1

I am trying to run the following command via paramiko exec_command. The stdout is different when I run this command via paramiko vs just pasting it into the shell in an ssh terminal session (I printed the command from the python script and then pasted that output directly to the ssh terminal).

The command is to submit jobs to an LSF queue based on when other jobs are completed, but I am not sure that my issue has anything to do with that:

bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script.sh

when the script is run via paramiko, this is the code and stdout: in:

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"

out:

100001) && done(100002) && done(100003
bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script1.sh



this is the end of the script

However, if I just log in to an ssh session and paste in bsub -w "done(100001) && done(100002) && done(100003)" < path/to/script.sh and this is in in/out: in:

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"

out:

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

I am guessing that this is an issue with paramiko vs an interactive session, but I am not certain.

Edit: tried adding get_pty=True (and also False) to exec_command, didn't make a difference. Edit #2: Printed $PATH in the shell and from paramiko, they were indeed different even with get_pty=True, with the one used when I log in manually having my username in the $PATH, which was not the case with the $PATH used by paramiko. So that's probably the problem, now to see if I can do anything about it. Edit #3: This does not sound encouraging, or at least it sounds like I might need help from the sysadmins. Edit #4: I tried invoking the shell script using ssh.invoke_shell and writing the command directly to stdin. Although that did invoke the script, the results were the same. But then I checked the $PATH and saw that I was indeed using the same $PATH as when I log in manually under invoke_shell. So I perhaps $PATH was not the problem?

My test use of invoke_shell was this:

    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())

Edit #5: The solution! It turns out that I needed to use a combination of things to get it working. One was running the command using bash --login (as suggested by @cxw), and then I also had to modify my command to triple-escape the inner quotation marks. So my working python was:

    cmd = "bsub -w \\\"" + jobz + "\\\" < " + exp_path + "/bsubmit2_" + EXPNAME + ".sh"
    explicit = 'bash --login -c "' + cmd + '"'
    print(explicit)
    stdin, stdout, stderr = ssh.exec_command(explicit)
Stonecraft
  • 860
  • 1
  • 12
  • 30
  • 1
    Possibly similar to https://stackoverflow.com/questions/55419330/some-unix-commands-fail-with-command-not-found-when-executed-using-python-p ? Might also have to do with the current working directory differing between paramiko and direct login. – cxw Apr 13 '19 at 10:26
  • All the commands actually have full paths, I just modified it slightly for posting purposes. – Stonecraft Apr 13 '19 at 10:28
  • As per the link it does appear to be a $PATH issue. – Stonecraft Apr 13 '19 at 11:51
  • 1
    Good to hear it! I'm going to vote to close as duplicate, then. – cxw Apr 13 '19 at 12:32
  • If I understand correctly, I want to either 1) call `bsub` using a full path or 2) use `invoke_shell()`. Does that sound right? I haven't got either of those to work yet, hopefully that will do it. – Stonecraft Apr 13 '19 at 12:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191784/discussion-between-thoughtcraft-and-cxw). – Stonecraft Apr 13 '19 at 13:46
  • 1
    As my answer to the duplicate question says, the **correct solution** is to fix your startup scripts not to set the environment differently for interactive and non-interactive sessions. – Martin Prikryl Apr 13 '19 at 15:50
  • I'm still unclear which startup scripts are used when and how to know (or how to know which I need when), but your answer got me to something that worked, I guess by making the right startup script be used. Thanks. – Stonecraft Apr 13 '19 at 17:25

0 Answers0