1

I have a shell script stored on my local machine. The script needs arguments as below:

#!/bin/bash
echo $1
echo $2

I need to run this script on a remote machine (without copying the script on the remote machine). I am using Python's Paramiko module to run the script and can invoke on the remote server without any issue.

The problem is I am not able to pass the two arguments to the remote server. Here is the snippet from my python code to execute the local script on the remote server:

with open("test.sh", "r") as f:
    mymodule = f.read()
c = paramiko.SSHClient()
k = paramiko.RSAKey.from_private_key(private_key_str)
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())

c.connect( hostname = "hostname", username = "user", pkey = k )
stdin, stdout, stderr = c.exec_command("/bin/bash - <<EOF\n{s}\nEOF".format(s=mymodule))

With bash I can simply use the below command:

ssh -i key user@IP bash -s < test.sh "$var1" "$var2"

Can someone help me with how to pass the two arguments to the remote server using Python?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Rakesh
  • 11
  • 3

1 Answers1

1

Do the same, what you are doing in the bash:

command = "/bin/bash -s {v1} {v2}".format(v1=var1, v2=var2)
stdin, stdout, stderr = c.exec_command(command)
stdin.write(mymodule)
stdin.close()

If you prefer the heredoc syntax, you need to use the single quotes, if you want the argument to be expanded:

command = "/bin/bash -s {v1} {v2} <<'EOF'\n{s}\nEOF".format(v1=var1,v2=var1,s=mymodule)
stdin, stdout, stderr = c.exec_command(command)

The same way as you would have to use the quotes in the bash:

ssh -i key user@IP bash -s "$var1" "$var2" <<'EOF'
echo $1
echo $2
EOF

Though as you have the script in a variable in your Python code, why don't you just modify the script itself? That would be way more straightforward, imo.


Obligatory warning: Do not use AutoAddPolicy – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • 2
    `command = "/bin/bash -s {v1} {v2} <<'EOF'\n{s}\nEOF".format(v1=var1,v2=var1,s=mymodule) stdin, stdout, stderr = c.exec_command(command)` worked. Thanks a tonnnn :) – Rakesh Nov 20 '20 at 19:13