The subprocess.call() function is not working - python

I was doing an exersize with the following task:
Write a python program to call an external command in Python.
As I could not solve it by my own I looked up the solution:
from subprocess import call
call(["ls", "-l"])
But the solution threw an Error:
FileNotFoundError: [WinError 2]
I also tried adding shell=True and for example leaving out the brackets like following:
subprocess.call('ls -l', shell=True)
In this case it tells me that the command "ls" could not be found.
I am working on windows 10,Python 3.8.2 32 bit
I am kind of lost and would be glad if someone could help.
Thank you!

ls is not a valid Windows CMD command.
For learning purpose, you may try CD for printing current directory, ie
import subprocess
subprocess.call(['CD'], shell=True)

Related

Python subprocess.Popen() does not find executable

I'm working on a script which should run a command in a new subprocess. At the moment im using the python subprocess.Popen() for this. My problem is that I can run commands like "dir" but not a installed program. When I open the cmd prompt and write "program -h" I am getting the normal help outprint. When I try to open it with Popen() I am getting an error that the program can not the found. It is like he is not finding the executable even if the cmd promt can find it when I look for it manually. For the test i used ncat as an example program.
import time
from subprocess import *
import subprocess
execom = "ncat -h" # DOES NOT WORK IN PYTHON BUT MANUALLY IN CMD
execom1 = "ncat -h -e cmd" # DOES NOT WORK IN PYTHON BUT MANUALLY IN CMD
execom2 = "dir" # WORKS
p = Popen(execom, shell=True)
out = p.communicate()[0]
Does someone know how to fix that?
EDIT:
I got the solution with the hint of 2e0byo. I added the paths to the systemvariabels but the system needed an extra restart to pass it. It worked without restart from cmd prompt but not from python script. After restart it works from both now.
Per the comments, the problem is just that ncat isn't in your PATH, so you need to add it:
import os
env = os.environ.copy()
env["PATH"] = r"C:\Program Files (x86)\Nmap;" + env["PATH"]
p = Popen(execom, env=env)
...
See this question for modifying the env.
As to why ncat isn't in your path I really don't know; I don't use Micro$oft Windoze very much. Perhaps someone will be along with a canonical answer to that question, or you can ask it over on superuser and see if someone knows how to set it up. If I needed this to be portable I would just check a bunch of folders for ncat and bail if I couldn't find it.

Calling subprocess.call(...) yields in error "[WinError 2] System can't find the specified file"

Hello my dear educated programmers,
I am trying to execute a command in the cmd prompt using Python. My research showed, that the subprocess module should give me what I need.
However, when using even the most basic test cases, Python always shows the error "[WinError 2] The system cannot find the file specified". I have checked, that subprocess.py is where it's supposed to be and there's no problems importing. There are loads of other questions on StackOverflow, but all of the which I read were about a specific file actually missing or some problems with setting correct paths, etc..
In my case though, I get this error even when testing things like:
import subprocess
subprocess.call("dir")
Any hints or tips what I could do wrong? I tried opening the cmd prompt as an admin, no luck still.
Thanks in advance!
I just tried the following in Windows 10 command prompt
>>> import subprocess
>>> subprocess.call("dir", shell=True)
Works fine. What OS/Python version are you using?

Running an exe file in python - not working

I have a crazy problem.
I have a cmd to run an exe file and it executes with no errors. The cmd in command prompt is
E:\project\cpp\myfirst.exe
I have to call this exe file within my python script. I use subprocess.call. But I get an error. The code and error is as follows
import subprocess
subprocess.call('E:\\project\\cpp\\myfirst.exe')
The error i get is
ERROR: Could not open myfirst setup file
1
I couldnt find the solution. I also tried os.system call. But still the same error. can you guys help me.
NOTE: the exe file is generated from a cpp code
thanks
The program seems to be seeking for some configuration file in the working directory, which is not always the same as the one where the executable is. Try instead:
import subprocess
subprocess.call('myfirst.exe', cwd=r'E:\project\cpp')
If you have written myfirst.exe yourself, consider changing the lookup logic so that it checks the executable's own directory.
Under Linux I have always found the popen mechanism to be more reliable.
from subprocess import Popen, PIPE process = Popen(['swfdump',
'/tmp/filename.swf', '-d'], stdout=PIPE, stderr=PIPE) stdout, stderr =process.communicate()
Answer taken from
How to use subprocess popen Python

subprocess.Popen(): OSError: [Errno 8] Exec format error in python?

Yesterday, I wrote and ran a python script which executes a shell using subprocess.Popen(command.split()) where command is string which constitutes .sh script and its argument. This script was working fine until yesterday. Today, I ran the same script and now I am continuously hitting this error.
p=subprocess.Popen(shell_command.split())
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
I know there are similar questions that have been asked before related to this question, but in my case I tried everything which doesn't solve my purpose. Using shell=True does not work because my shell script calls an another shell script before which some environment has to be set in order to run that script. I am badly stuck in this. I just restart my system once. I am using ubuntu 12.04
EDIT:
import subprocess
import os
import sys
arg1=sys.argv[1]
arg2=sys.argve[2]
shell_command = 'my_path/my_shell.sh ' + arg1 + ' '+ arg2
P = subprocess.Popen(shell_command.split())
P.wait()
my_shell.sh:
arg1=$1
arg2=$2
cd $TOP
setup the environment and run shell script
build the kernel ...
execute shell command .....
I solved this by putting this line at the top of the called shell script:
#!/bin/sh
That will guarantee that the system always uses the correct interpreter when running your script.
Following statement worked for me
subprocess.Popen(['sh','my_script.sh'])
The error message suggests that the external program is not a valid executable.
As #tripleee said, there is an issue executing your script. Make sure:
Change the shell command to "./my_path/my_script.sh" or "/bin/bash my_path/my_script.sh". Account for environment variables, if necessary.
Both scripts have execute bit set (chmod +x)
The files exist at the location you think they do. (Use abspath or verify environment)
The files have contents
Try removing and re-typing the first line. I recommend killing the whole line, and hitting backspace several times in case there's a non-printable character before the #!
See also: Why is '#!/usr/bin/env python' supposedly more correct than just '#!/usr/bin/python'?
This can also happen if the binary is not meant to run on your system.
I'm on OSX, but the binary I was running is not meant for OSX, as I saw from using file path/to/binary:
webui/bin/wkhtmltopdf: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=b6566a9e44c43a0eebf18d8c1dc6cb616801a77e, stripped
The error is because the executables are not given in the prescribed format for subprocess to execute it.
example:
shell_command1 = r"/path/to/executable/shell/file"
shell_command2 = r"./path/to/executable/shell/file"
subprocess.call(shell_command1) or subprocess.Popen(shell_command1) will not be able to run shell_command1 because subprocess needs an executable command like (mailx, ls, ping, etc.) or executable script like shell_command2 or you need to specify command like this
subprocess.call(["sh", shell_command1])
subprocess.Popen(["sh", shell_command1])
but however, you can use os.system() or os.Popen() as well
I am currently facing the same issue. I noticed that using shell=True argument, like subprocess.Popen(shell_command.split(), shell=True) works as inteded.
It is recommended to install the package binfmt-support to help the system better recognize the scipts. It helps regardless of whether they have a shebang line.

Toggle process with Python-script (kill when running, start when not running)

I'm currently running an OpenELEC (XBMC) installation on a Raspberry Pi and installed a tool named "Hyperion" which takes care of the connected Ambilight. I'm a total noob when it comes to Python-programming, so here's my question:
How can I run a script that checks if a process with a specific string in its name is running and:
kill the process when it's running
start the process when it's not running
The goal of this is to have one script that toggles the Ambilight. Any idea how to achieve this?
You may want to have a look at the subprocess module which can run shell commands from Python. For instance, have a look at this answer. You can then get the stdout from the shell command to a variable. I suspect you are going to need the pidof shell command.
The basic idea would be along the lines of:
import subprocess
try:
subprocess.check_output(["pidof", "-s", "-x", "hyperiond"])
except subprocess.CalledProcessError:
# spawn the process using a shell command with subprocess.Popen
subprocess.Popen("hyperiond")
else:
# kill the process using a shell command with subprocess.call
subprocess.call("kill %s" % output)
I've tested this code in Ubuntu with bash as the process and it works as expected. In your comments you note that you are getting file not found errors. You can try putting the complete path to pidof in your check_output call. This can be found using which pidof from the terminal. The code for my system would then become
subprocess.check_output(["/bin/pidof", "-s", "-x", "hyperiond"])
Your path may differ. On windows adding shell=True to the check_output arguments fixes this issue but I don't think this is relevant for Linux.
Thanks so much for your help #will-hart, I finally got it working. Needed to change some details because the script kept saying that "output" is not defined. Here's how it now looks like:
#!/usr/bin/env python
import subprocess
from subprocess import call
try:
subprocess.check_output(["pidof", "hyperiond"])
except subprocess.CalledProcessError:
subprocess.Popen(["/storage/hyperion/bin/hyperiond.sh", "/storage/.config/hyperion.config.json"])
else:
subprocess.call(["killall", "hyperiond"])

Categories