I have developed a Python application which needs to call a bash script stored in another computer (Raspberry Pi).
I don't need to get any return value nor confirmation.
What are the feasible ways to do that?
Thanks!
From the shell you could do it like this:
ssh pi#theraspberrypi "./myscript"
To run a shell command from in Python:
import os
os.system("ssh pi#theraspberrypi ./myscript")
Or, as Eevee suggested below:
import subprocess
subprocess.call(['ssh pi#theraspberrypi ./myscript'], shell=True)
Of course, you will probably want to put your public key in the raspberry pi's authorized_keys file so it won't prompt for a password.
Related
I'm new in a company for IT and very few people here know Python so I can't ask then for help.
The problem: I need to create a script in Python that connects via ssh from my VM to my client server, after I access with my script I need to find a log file and search for a few data.
I tested my script within my Windows with a copy of that file and it searched everything that I need. However, I don't know how to do that connection via SSH.
I tried like this but I don't know where to start:
from subprocess import Popen, PIPE
import sys
ssh = subprocess.check_output(['ssh', 'my_server', 'password'], shell = True)
ssh.stdin.write("cd /path/")
ssh.stdin.write("cat file | grep err|error")
This generates a error "name 'subprocess' is not defined".
I don't understand how to use the subprocess nor how to begin to develop the solution.
Note: I can't use Paramiko because I don't have permission to install packages via pip or download the package manually.
You didn't import subprocess itself so you can't refer to it.
check_output simply runs a process and waits for it to finish, so you can't use that to run a process you want to interact with. But there is nothing interactive here, so let's use that actually.
The first argument to subprocess.Popen() and friends is either a string for the shell to parse, with shell=True; or a list of token passed directly to exec with no shell involved. (On some platforms, passing a list of tokens with shell=True actually happens to work, but this is coincidental, and could change in a future version of Python.)
ssh myhost password will try to run the command password on myhost so that's not what you want. Probably you should simply set things up for passwordless SSH in the first place.
... But you can use this syntax to run the commands in one go; just pass the shell commands to ssh as a string.
from subprocess import check_output
#import sys # Remove unused import
result = check_output(['ssh', 'my_server',
# Fix quoting and Useless Use of Cat, and pointless cd
"grep 'err|error' /path/file"])
There is any possibility to run the python script in remote machine with out transfer files using SCP or better method? I have search a lot of libraries for solve this issue. But did not find the best solution for it.
I have found some libraries which perform SSH and SCP to remote machine using python script. In their approach first copy files to remote system using SCP and execute command over SSH.
Thanking you
You could use fabric.
Obviously it does depend on what exactly you want your remote python script to do, but it has a lot of helper functions for interacting with the OS including file upload & download but it's written all in Python.
You can invoke python with a flag to read the script from its standard input, and then feed the script to the python instance through the ssh connection, for example:
cat /some/script.py | ssh user#host 'python -'
Running python - will cause the python interpreter to read the script from the process's standard input. In this case, the standard input of the ssh process is passed to the remote system as the standard input of the python instance.
You can supply additional command-line arguments to the python script, if desired:
cat /some/script.py | ssh user#host 'python - arg1 arg2...'
Note that any import statements in the python script will be resolved on the remote system, so the script has to limit itself to modules which are available to the remote python interpreter.
Sure.
ssh remotehost python -c "'print(5)'"
A script needs not to be copied to execute it. The Python interpreter can run a script which is given as argument.
Double quoting is necessary (and will quickly become a hassle) because one level of quoting is removed by the ssh call and another is still necessary to group the script into one argument for the python call.
Multiline is also no problem:
ssh remotehost python -c "'
import random
print(random.random())'"
will print something like
0.998373816572
Just be aware of the quoting stuff when you use ' or " in your Python script as well.
Another option is to have the script in a variable and then use printf to quote the contents properly:
a='
import random
print(random.random())'
# or use something like a=$(cat myscript.py)
ssh ttiqadm#ttiq-hv02 python -c "$(printf "%q" "$a")"
What I want is to have a desktop shortcut that will run a script. I've been trying to use batch and Python, but I don't really care what language if it works. I need the script to open a bash shell (Windows Subsystem for Linux) and execute simple commands while keeping the shell open. At first, I thought this would simple, but now I'm questioning if it's even possible. I made a simple batch file that would get as far as opening bash and keep it open, but the test command I put in didn't make it to the shell. (I didn't really expect it to but I can't think of a good way to do this, so I've just been trying random stuff). Here is the batch file I used:
bash
cowsay test
PAUSE
After this, I tried using a Python script to open bash and run a shell script that would keep the shell open and execute commands. Here is the Python script:
import os
import time
os.system("start /wait bash /c {./test.sh}")
while 1:
time.sleep(2)
For some reason, this gives an error saying it can't find bash. This isn't really for a project or anything. It's actually for a friend's computer as kind of a joke, but I would really like to know if this is possible. If anyone has any ideas how this could work, I would appreciate it because I'm out of ideas and can't find any other similar questions.
Yes, you can do something like this
import subprocess
from subprocess import Popen
p = Popen("batch.bat", cwd=r"C:\Path\to\batchfolder")
stdout, stderr = p.communicate()
I'm writing a Python script that will run on a Raspberry that will read the temperature from a sensor and log to Thingspeak. I have this working with a bash script but wan't to do it with Python since it will be easier to manipulate and check the read values. The sensor reading is done with a library called loldht. I was trying to do it like this:
from subprocess import STDOUT, check_output
output = check_output("/home/pi/bin/lol_dht22/loldht", timeout=10)
The problem is that I have to run the library with sudo to be able to access the pins. I will run the script as a cron. Is it possible to run this with sudo?
Or could I create a bash script that executes 'sudo loldht' and then run the bash script from python?
I will run the script as a cron. Is it possible to run this with sudo?
You can put python script.py in the cron of a user with sufficient privileges (e.g. root or a user with permissions to files and devices in question)
I don't know which OS you're using, but if Raspbian is close to Debian, there is no need for sudo or root, just use a user with sufficient permissions.
It seems I can also do this check_output check_output(["sudo", "/home/pi/bin/lol_dht22/loldht", "7"], timeout=10)
Sure but the unix user that's going to invoke that Python script will need the sudo privilege (Otherwise can't call the sudo from subprocess). In which case you might as well do as above, run the cron from a user with the required permissions.
You can run sudo commands with cron. Just use sudo crontab -e to set the cron and it should work fine.
You should very careful with running things as root. Since root has access to everything, a simple error can potentially render the system unusable.
The proper way to have access to the hardware as a normal user is to change the permissions on the required device files.
It seems that the utility you mention uses the WiringPi library. Some digging in the source code indicates that it uses the /dev/gpiomem (or /dev/mem) devices.
On raspbian, device permissions are set with udev. See here and also here.
You could give every user access to /dev/gpiomem and other gpio devices by creating a file e.g. /etc/udev/rules.d/local.rules and putting the following text in it:
ACTION=="add", KERNEL=="gpio*", MODE="0666"
ACTION=="add", KERNEL=="i2c-[0-9]*", MODE="0666"
The first line makes the gpio devices available, the second one I2C devices.
i want to run and control PSFTP from a Python script in order to get log files from a UNIX box onto my Windows machine.
I can start up PSFTP and log in but when i try to run a command remotely such as 'cd' it isn't recognised by PSFTP and is just run in the terminal when i close PSFTP.
The code which i am trying to run is as follows:
import os
os.system("<directory> -l <username> -pw <password>" )
os.system("cd <anotherDirectory>")
i was just wondering if this is actually possible. Or if there is a better way to do this in Python.
Thanks.
You'll need to run PSFTP as a subprocess and speak directly with the process. os.system spawns a separate subshell each time it's invoked so it doesn't work like typing commands sequentially into a command prompt window. Take a look at the documentation for the standard Python subprocess module. You should be able to accomplish your goal from there. Alternatively, there are a few Python SSH packages available such as paramiko and Twisted. If you're already happy with PSFTP, I'd definitely stick with trying to make it work first though.
Subprocess module hint:
# The following line spawns the psftp process and binds its standard input
# to p.stdin and its standard output to p.stdout
p = subprocess.Popen('psftp -l testuser -pw testpass'.split(),
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# Send the 'cd some_directory' command to the process as if a user were
# typing it at the command line
p.stdin.write('cd some_directory\n')
This has sort of been answered in: SFTP in Python? (platform independent)
http://www.lag.net/paramiko/
The advantage to the pure python approach is that you don't always need psftp installed.