How to know if a service is installed - python

I'm looking for a way to check with a Python script if a service is installed. For example, if I want to check than a SSH server in installed/running/down in command line, I used :
service sshd status
If the service is not installed, I have a message like this:
sshd.service
Loaded: not-found (Reason: No such file or directory)
Active: inactive (dead)
So, I used a subprocess check_output to get this three line but the python script is not working. I used shell=True to get the output but it doen't work. Is it the right solution to find if a service is installed or an another method is existing and much more efficient?
There is my python script:
import subprocess
from shlex import split
output = subprocess.check_output(split("service sshd status"), shell=True)
if "Loaded: not-found" in output:
print "SSH server not installed"
The probleme with this code is a subprocess.CalledProcessError: Command returned non-zero exit status 1. I know that's when a command line return something which doesn't exist but I need the result as I write the command in a shell

Choose some different systemctl call, which differs for existing and non-existing services. For example
systemctl cat sshd
will return exit code 0 if the service exists and 1 if not. And it should be quite easy to check, isn't it?

Just catch the error and avoid shell=True:
import subprocess
try:
output = subprocess.check_output(["service", "sshd", "status"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print(e.output)
print(e.returncode)

Related

Python: communication between an app and terminal which is asking for Admins password

I’m trying to accomplish the following but no luck, any suggestions?
⇒ My app will run a command that requires admin’s password, if you run the command in Terminal, the command will stop asking for the password, however, if you run it within Python, it will just skip that and will end with error (as Admin's password weren't entered. I have used elevate module to launch the app as root, however, the command im using doesn't allow to run as a root :
Do not run this script with root privileges. Do not use 'sudo'
Any suggestions how to communicate between cli and python when cli is waiting for the admins password instead of just skipping it?
Thank you all
My code:
Import os
os.system('killall Box')
os.system('/Library/Application\ Support/Box/uninstall_box_drive')
Result:
/usr/local/bin/python3.10 /Users/user/PycharmProjects/pythonProjectBoxUnsaved/venv/test.py
No matching processes belonging to you were found
Unload failed: 5: Input/output error
Try running `launchctl bootout` as root for richer errors.
0
/usr/bin/fileproviderctl
File provider com.box.desktop.boxfileprovider/Box not found. Available providers:
- iCloud Drive (hidden)
com.apple.CloudDocs.MobileDocumentsFileProvider
~/L{5}y/M{14}s
fileproviderctl: can't find domain for com.box.desktop.boxfileprovider/Box: (null)
No matching processes belonging to you were found
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
* * * * * *
Process finished with exit code 0
Error when trying to run the code
Error when using 'elevate' module
I have also tried pexpect, will not work, code below:
import os
import pexpect
os.system('killall Box')
child = pexpect.spawn('/Library/Application\ Support/Box/uninstall_box_drive')
print(child.after)
child.expect_exact('Password:')
print(child.after)
child.sendline('my_password')
print(child.after)
result below:
None
b'Password:'
b'Password:'
Solved it.
Had to include Bash path in the spawn arguments:
cmd = "/Library/Application\ Support/Box/uninstall_box_drive"
child = pexpect.spawn("/bin/bash", ["-c", cmd])

Running Newman command with subprocess

I have a Newman command that is part of my script. I'd like the entire script to quit (or go back to the main menu) when the collection encounters an error.
from subprocess import CalledProcessError, Popen, PIPE
from io import TextIOWrapper
def run_sh(command):
process = Popen(shlex.split(command), stdout=PIPE)
for line in TextIOWrapper(process.stdout, newline=""):
print(line, "")
cmd = newman run "My_Collection.postman_collection.json" --folder "My_Folder" -e ../../Postman/Environments/My_Environment.json -d "CREDS.txt" -r cli,csv -n 1 --reporter-csv-includeBody --reporter-csv-export ./RESPONSES.csv
The run_sh(cmd) is part of a bigger script. I'd like the script to not carry on to the next step if errors are encountered when running the collection. Using try and except won't work because the run_sh command successfully goes through (it runs the collection but the collection yields errors).
Example of an error:
# failure detail
1. AssertionError Status code is 202
expected response to have status code 202 but got 401
at assertion:0 in test-script
inside "MY FOLDER"
What would be the best way to go about this?

Retrieve List of Bluetooth Devices Using Python 3 and Terminal

When using the Linux terminal inside the Raspberry pi, i have to use only 3 commands to retrieve a list of Bluetooth capable devices in the area. These are the commands that are executed in order:
"sudo bluetoothctl"
"agent on"
"scan on"
the final command above will over-time retrieve a list of scanned devices. When i manually put it into my raspberry pi terminal it works (found instrustions from here: Instruction Link)
QUESTION: how do i translate the series of commands above into a Python 3 script using the standard subprocess module?
I Tried:
import time
import subprocess
arguments = ["sudo", "bluetoothctl"] #to be able to access Bluetooth commands
output = subprocess.Popen(arguments, shell=True)
time.sleep(0.1)
arguments = ["agent", "on"]
output = subprocess.Popen(arguments, shell=True)
time.sleep(0.1)
arguments = ["scan", "on"]
output = subprocess.check_output(arguments, shell=True)
time.sleep(0.1)
print(output) #not even close huh.. yea..
As you can see i'm pretty new to both Linux terminal commands and the subprocess module. Therefore any help and guidance is greatly appreciated!
UPDATE: i am able to get my first command sudo bluetoothctl to work as it returns list of previously paired devices. However when i get to the next command output = subprocess.Popen("agent on", shell=True) it returns a message: /bin/sh: 1: agent: not found. How do i get my other commands to work?
New code:
import time
import subprocess
output = subprocess.Popen("sudo bluetoothctl", shell=True)
time.sleep(0.1)
output = subprocess.Popen("agent on", shell=True)
time.sleep(0.1)
output = subprocess.check_output("scan on", shell=True)
time.sleep(2)
What the terminal spits out:
[NEW] Controller XX:XX:XX:XX:XX:XX raspberrypi [default]
[NEW] Device XX:XX:XX:XX:XX:XX Galaxy J3 Emerge
[bluetooth]# /bin/sh: 1: agent: not found
/bin/sh: 1: scan: not found
Traceback (most recent call last):
File "/home/pi/pywork/test.py", line 9, in <module>
output = subprocess.check_output("scan on", shell=True)
File "/usr/lib/python3.5/subprocess.py", line 316, in check_output
**kwargs).stdout
File "/usr/lib/python3.5/subprocess.py", line 398, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'scan on' returned non-zero exit status 127
Process finished with exit code 1
Any ideas on how to get this second command to work?
TLDR;
The issue of the above is related to the invocation of suprocess.check_output, with parameter shell=True, you should use string instead of a list of arguments
Here are some details.
UPDATE:
I assume that the reason is that it's not invoked in the same shell session, so it didn't find an agent. Depending on what you're trying to achieve, you should either use the same session (for example as in this case) or use a python library like PyBluez to control the Bluetooth devices (which I would recommend)
I am currently doing a similar function. Have you realized this function yet? After sending Bluetooth CTL with Popen, a pipeline will be opened. The subsequent agent on and scan on must be sent in the opened pipeline, rather than opening a new pipeline with Popen.
Regardless of the fact this question was posted years ago some wanderer might find the line below useful. Nevermind sudo as not necessary.
bt = subprocess.Popen(["sudo", "bluetoothctl", "scan", "on"], stdin=subprocess.PIPE)

Executing DevCon CMD command from python

I want to restart driver with DevCon from python script. It works from command line with this command:
devcon restart \"sd0007322081041363_kcanv\"
I tried this:
os.system("devcon restart \"sd0007322081041363_kcanv\"")
with result:
'devcon' is not recognized as an internal or external command
I read that os.system is obsolete and i need to use subprocess.check_output so i try this:
subprocess.check_output(['devcon', 'restart', '"sd0007322081041363_kcanv"'])
with result:
WindowsError:[Error 2] The system cannot find the file specified
and this:
subprocess.check_output('devcon restart "sd0007322081041363_kcanv"', shell=True)
with result:
subprocess.CalledProcessError: Command 'devcon restart "sd0007322081041363_kcanv"' returned non-zero exit status 1
and this:
subprocess.Popen("devcon restart \"sd0007322081041363_kcanv\"", shell=True, stdout=subprocess.PIPE).stdout.read()
result:
'devcon' is not recognized as an internal or external command
and this:
try:
subprocess.check_output('devcon disable "sd0007322081041363_kcanv" /f',shell=True,stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
with result:
RuntimeError: command 'devcon disable "sd0007322081041363_kcanv" /f' return with errpr (cpde 1): 'devcon' is not recognized as an internal or external command, operable program or batch file
devcon.exe is under Windows/System32 and it is set in system path.
I know that this can be duplicate question but I have tried many solution on stackoverflow but i van't resolve this issue.
Finally, I came up with a solution. I tried many things but this is what works for me:
copy devcon.exe from C:\Windows\System32 and put it to C:\Windows\SysWOW64.
my code:
try:
subprocess.check_output('C:\\Windows\\SysWOW64\\devcon.exe restart "sd0007322081041363_kcanv" /f',shell=True,stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))

Run program from command line what prompts password and automatically provide password for it (cmd.exe, python)

I have command line program what prompts password:
> cwrsync root#NN.NN.NN.NN:/src /cygdrive/c/dst
Output (when i run it from cmd.exe command line):
root#NN.NN.NN.NN's password:
When i input password manually, all OK. Output:
skipping directory src
I want to provide password for it from command line or python script automatically.
I tried:
One. From command line:
> echo pass|cwrsync -r root#NN.NN.NN.NN:/src /cygdrive/c/dst
Not working. Output:
root#NN.NN.NN.NN's password:
Two. From python script. test.py:
import subprocess
cmd = "cwrsync -r root#NN.NN.NN.NN:/src /cygdrive/c/dst"
proc = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
std1, std2 = proc.communicate("pass")
print std1print std2
Not workin. Output:
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(235) [Receiver=3.1.1]
It is common that security oriented programs ask for password on direct io instead of reading stdin. And as :
echo pass|cwrsync -r root#NN.NN.NN.NN:/src /cygdrive/c/dst
did ask password, I presume that csrsync directly reads from console.
In that case you cannot automate it without some work and low level programming, because you will have to simulate keyboard actions. You should instead search the documentations, because as it looks like it uses an underlying ssh, it is likely to accept a public key pair. If it accept one without passphrase, you should be able to automate it.
Try sending a newline in your stdin string communicate call like so:
import subprocess
cmd = ['cwrsync', '-r', 'root#NN.NN.NN.NN:/src', '/cygdrive/c/dst']
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
shell=True)
std1, std2 = proc.communicate("pass\r\n\r\n")
print std1
print std2
You should also see if it works with shell=False (from subprocess docs):
Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.

Categories