Pipe output of local script, ran on remote machine, to local python script
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Pipe output of local script, ran on remote machine, to local python script
Background:
Python program adjusting router configurations (OSPF) on WISP main backhaul system due to radio state changes.
Goal:
Run local shell script on remote router, and return the output to the parent Python program.
Problem:
Not understanding how to direct or redirect the output
I can run the shell script stand alone from a terminal and it prints the output to the terminal screen but when I call it from python using subprocess.check_output I get an empty string and no errors.
This is the stand alone command: (there are 3 args passed to route-cost.sh, the target router hostname, the target interface, and the OSPF cost to check/set)
#!/bin/vbash
hname=$1
iface=$2
cost=$3
checkcost=" cost $3"
source /opt/vyatta/etc/functions/script-template
if [ `hostname` = "$hname" ]; then
configure
currentcost=`show interfaces ethernet $iface ip ospf cost`
if [ "$currentcost" != "$checkcost" ]; then
echo "$hname $iface cost set to $cost"
set interfaces ethernet $iface ip ospf cost $cost
commit
save
else
echo "$hname $iface cost already set to $cost"
fi
else
echo "Hostname doesn't match"
fi
exit
In an effort to move on I regressed to copying the script to the remote routers into persistent storage and running it remotely. One file write won't wear out the flash enough to matter and it gets the job done. Still it bothers me I can't get it done the "right" way.
Now if I ever want to make changes to said script I will have to manipulate all our routers again and make sure they have the updated version as opposed to changing the one single script locally on the management server that should get ran remotely.
I really thing the bug, if it is, is in python's subprocess module. I don't think it is handling all the arguments exactly like an open shell does when I test the command. I don't have the energy to prove that nor the expertise to fix it if I do prove it.
That will run the script "vbash" on the remote machine and use its output as input for "route-cost" which will run on the local machine. If you want "vbash" to run locally and "route-cost" to run on the remote, then move the use of "ssh"
route-cost.sh is stored on the local machine. It needs to be ran by vbash on the remote machine. But the whole thing is being ran from a python program on the same local machine using the subprocess.check_output function.
route-cost.sh runs as it should when called from a terminal on the local machine like I previously mentioned.
You mention in the first post a python script and a shell script. Both should identify the interpreter to be used in the first line of the script. The interpreter is likely to be one of these:
/usr/bin/python
/usr/bin/perl
/bin/sh
/bin/bash
It sounds like you are trying to run one script on a remote computer and pass the output to a script on the local computer. Or is it the reverse?
Edit: I now see your latest post. See my earlier one and swap the redirect ( < ) for a pipe ( | ) in your example or try one of the syntaxes given above.
Last edited by Turbocapitalist; 07-03-2016 at 01:41 AM.
It sounds like you are trying to run one script on a remote computer and pass the output to a script on the local computer.
Correct, I am trying to run one script on a remote router and pass the output to a python script on the local computer.
I understand the interpreter line, #!/bin/vbash for the script running on the remote router and #!/usr/bin/python for the local python script.
I'll give your examples a try. Thank you very much for the suggestion. Like I said, I had moved on, but I really would like to get this done right. Unless this whole idea fails this should be a long term operation.
There some good but abstract explanations of redirects and pipes, but it's harder to find something basic. The redirects send output to or from a file. So if you were to use a redirect with a remote script, it could go something like this:
I lack a good understanding of the finer points of piping and redirects. So I find myself programming around those weak areas. So many ways to get things done but usually only a couple nice ways.
If I understand it well you want to execute it from python. But the redirection "<" is not part of the command you wanted to execute, therefore the arg list is not ok (in your original post).
I do not know if your command in post #7 works properly (I mean without python), or that line was also incorrect.
I lack a good understanding of the finer points of piping and redirects.
The pipes are more useful in this case, if I understand your set up. Pipes are pretty simple and you can even use them with ssh to get data from a program on one machine to a program on another. See #4 above for going either direction with the data. The pipes always flow from left to right so you have to line up your programs with that in mind.
I'm fooling around with it again today. Haven't made any progress yet. I'm thankful for the help but also happy to leave it as is if nobody feels like tagging along here.
One thing that makes it a bit more trippy, I think, is the 3 args that need to be passed to the script when it is run on the remote machine.
In a terminal I tried this:
Code:
cat route-cost.sh | ssh username@10.1.1.19
It runs on the remote machine but of course there is no args so the script properly dumps back the appropriate error.
So somehow the list getting passed to subprocess.check_output is not being treated the same as when it's ran in a terminal. The "-q" is getting applied to "cat" instead of "ssh".
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.