subprocess gives an error. "The system cannot find the file specified" - python

This is my code:
import urllib
import requests
from bs4 import *
from subprocess import Popen,PIPE
import os
connectString = 'SYSTEM/mediadot123'
def runSqlQuery(sqlCommand, connectString):
session = Popen(['sqlplus', '-S', connectString], stdin=PIPE, stdout=PIPE, stderr=PIPE)
session.stdin.write(sqlCommand)
return session.communicate()
session = Popen(['sqlplus','-S','hr/hr'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()
sqlCommand = "insert into food(title, recipe, image) values ('bla','bla','bla');"
queryResult, errorMessage = runSqlQuery(sqlCommand, connectString)
print queryResult
And it gives me the following error:
C:\Python27\python.exe C:/Users/Umer/PycharmProjects/DATACRAWLER/main.py
Traceback (most recent call last):
File "C:/Users/Umer/PycharmProjects/DATACRAWLER/main.py", line 38, in <module>
session = subprocess.Popen(['sqlplus','-S','hr/hr'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "C:\Python27\lib\subprocess.py", line 710, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 958, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Consider using an absolute path for your command-execution.
Some binaries are not located in PATH depending on your user, system and software installation.
To find out where sqlplus resides, run the following in cmd.exe: where sqlplus and that should give you the absolute path.
Then simply do:
Popen(['C:/path/sqlplus.exe', '-S', ...])
Also to find out what's actually in your PATH environment variable, you could do the following:
print(os.environ['PATH'])

Related

Print bash history using python

I have to print bash history using subprocess package.
import subprocess
co = subprocess.Popen(['history'], stdout = subprocess.PIPE)
History = co.stdout.read()
print("----------History----------" + "\n" + History)
but they prompt an error
Traceback (most recent call last):
File "test.py", line 4, in <module>
co = subprocess.Popen(['history'], stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Normally, you would need to add shell=True argument to your Popen call:
co = subprocess.Popen(['history'], shell=True, stdout = subprocess.PIPE)
Or to manually specify the shell you want to call.
co = subprocess.Popen(['/bin/bash', '-c', 'history'], stdout = subprocess.PIPE)
Unfortunately, in this particular case it won't help, because bash has empty history when used non-interactively.
A working solution would be to read ${HOME}/.bash_history manually.
Kit is correct, reading ~/.bash_history may be a better option:
from os.path import join, expanduser
with open(join(expanduser('~'), '.bash_history'), 'r') as f:
for line in f:
print(line)

subprocess.call command for executing "ci -u <filename>"

I am trying to execute a python script that first creates a new file(if it does not exist) and then executes ci(on the newly created file) to create a rcs file with initial revision number. But when I run the script it asks me for description and ending with period '.'. I want this part to be automated with a default description and create the rcs file without user input. Any help would be much appreciated. Following is my code:
import os
import subprocesss
if os.path.isfile(location):
print "File already exists"
else:
f = open(location,'a')
subprocess.call(["ci", "-u", location])
f.close()
print "new file has been created"
I tried this and I am getting the following error:
import os
import subprocess
if os.path.isfile(location):
print "File already exists"
else:
f = open(location,'a')
cmd = "ci -u "+location
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
stdout_data = p.communicate(input='change\n.')[0]
f.close()
print "new file has been created"
Traceback (most recent call last):
File "testshell.py", line 15, in
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
File "/usr/local/pythonbrew/pythons/Python-2.7/lib/python2.7/subprocess.py", line 672, in init
errread, errwrite)
File "/usr/local/pythonbrew/pythons/Python-2.7/lib/python2.7/subprocess.py", line 1201, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
You can use subprocess.call's stdin argument to give the subprocess a file-like object to use as its standard input (what you would enter by hand).
The StringIO module contains a class called StringIO that offers a file-like interface to an in-memory string.
Combining these two pieces together will let you send a specific string to ci, as if the user had entered it manually
from StringIO import StringIO
import subprocess
...
subprocess.call(['command', 'with', 'args'], stdin=StringIO('StandardInput'))
Alternately, as CharlesDuffy suggests, you can use Popen and its communicate method:
import subprocess
proc = subprocess.Popen(['command', 'with', 'args'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate('StandardInput')

error while running Popen

I am running into following error when trying to run a command using Popen,what is wrong here?
cmd = "export COMMANDER_SERVER=commander.company.com"
Pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
(output, error) = Pipe.communicate()
Error:-
Traceback (most recent call last):
File "test_ectool.py", line 26, in <module>
main()
File "test_ectool.py", line 13, in main
Pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
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 2] No such file or directory
You need to separate the arguments from the command and give a list to Popen.
As Kenster's comment said, even if your command worked, you would only succeed in modifying an environmental variable inside a sub-shell not the main shell.
You will not be able run run export this way, because it is not a program. It is a bash built-in.
Here is an example of a command that does work, with the correct semantics.
from subprocess import Popen,PIPE
cmd = "echo COMMANDER_SERVER=commander.company.com"
Pipe = Popen(cmd.split(), stdout=PIPE, stderr=PIPE)
(output, error) = Pipe.communicate()
print output
merlin2011's answer is incorrect regarding the command string for Popen (point #1). From the Python docs:
args should be a sequence of program arguments or else a single string.
As other people have stated, the environment variable will not be saved. For that, you need to use os.environ['VARNAME'] = value. If you want to use other bash builtins, then you must pass shell=True as an argument to Popen.

How to use Subprocess in Windows

I am trying to save the result or function runcmd in the variable Result.
Here is what I have tried:
import subprocess
def runcmd(cmd):
x = subprocess.Popen(cmd, stdout=subprocess.PIPE)
Result = x.communicate(stdout)
return Result
runcmd("dir")
When I run ths code, I get this result:
Traceback (most recent call last):
File "C:\Python27\MyPython\MyCode.py", line 7, in <module>
runcmd("dir")
File "C:\Python27\MyPython\MyCode.py", line 4, in runcmd
x = subprocess.Popen(cmd, stdout=subprocess.PIPE)
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 893, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
What could I do to fix this?
I think what you are looking for is os.listdir()
check out the os module for more info
an example:
>>> import os
>>> l = os.listdir()
>>> print (l)
['DLLs', 'Doc', 'google-python-exercises', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.e
xe', 'README.txt', 'tcl', 'Tools', 'VS2010Cmd.lnk']
>>>
You could also read the output into a list:
result = []
process = subprocess.Popen('dir',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
for line in process.stdout:
result.append(line)
errcode = process.returncode
for line in result:
print(line)
As far as I know, dir is a built in command of the shell in Windows and thus not a file available for execution as a program. Which is probably why subprocess.Popen cannot find it. But you can try adding shell=True to the Popen() construtor call like this:
def runcmd(cmd):
x = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
return x.communicate(stdout)
runcmd("dir")
If shell=True doesn't help, you're out of luck executing dir directly. But then you can make a .bat file and put a call to dir there instead, and then invoke that .bat file from Python instead.
btw also check out the PEP8!
P.S As Mark Ransom pointed out in a comment, you could just use ['cmd', '/c', 'dir'] as the value of cmd instead of the .bat hack if shell=True fails to fix the issue.

Cannot run ffmpeg in subproces.call

So, I have a simple class where I am trying to save a string response from a terminal ffmpeg command into an object property:
import os
import subprocess
class Movie(object):
absolute_path = None
movie_info = None
def __init__(self, path):
self.absolute_path = "%s/%s" % (os.getcwd(), path)
if(os.path.exists(self.absolute_path) is False):
raise IOError("File does not exist")
def get_movie_info(self):
ffmpeg_command = "ffmpeg -i %s" % self.absolute_path
self.movie_info = subprocess.call(ffmpeg_command)
print self.movie_info
When I then run this command in cmd:
import os
import sys
sys.path.append(os.getcwd())
from Encode.Movie import Movie
try:
movie = Movie("tests/test_1.mpg")
movie.get_movie_info()
except IOError as e:
print e
I get this exception:
richard#richard-desktop:~/projects/hello-python$ python main.py
Traceback (most recent call last):
File "main.py", line 9, in <module>
movie.get_movie_info()
File "/home/richard/projects/hello-python/Encode/Movie.py", line 16, in get_movie_info
self.movie_info = subprocess.call(ffmpeg_command)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
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 2] No such file or directory
The path is correct because when I do print self.absolute_path before subprocess.call(), I get:
/home/richard/projects/hello-python/tests/test_1.mpg
And this file exists.
The problem is
ffmpeg_command = "ffmpeg -i %s" % self.absolute_path
self.movie_info = subprocess.call(ffmpeg_command)
you give a single string as command line, but you omit the parameter shell=True.
The recommended way is, however, to do
ffmpeg_command = ["ffmpeg", "-i", self.absolute_path]
self.movie_info = subprocess.call(ffmpeg_command)
in order to give the command and arguments separately. This way, you have no problems with quoting etc, and you omit an unnecessary shell call.
BTW, If you want to store the output of a command in a variable, then you should use check_output instead of a call
http://docs.python.org/library/subprocess.html#subprocess.check_output
I actually used this way of getting the output from ffmpeg as it is an error output:
ffmpeg_command = ["avconv", "-i", self.absolute_path]
p = Popen(ffmpeg_command, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()

Categories