I've discovered Oracle's SQLCL and have been able to make it work in the terminal. I've also been able to make it work in Python, up through entering the actual SQL query.
My code in Python looks like this:
import subprocess
import time
import os
os.chdir("C:/sqlcl/bin")
subprocess.run(["sql", "username/password#//database-oracle.datamore.com/moreprod.more:1521"])
At this point, I get the "SQL>" prompt showing that Oracle is ready to take my query. What I'd like to do is enter the location to a script and have it be executed, something like:
#C:/Users/username/queries/test-query.sql;
Basically, I need a way to pass a SQL statement or a script location via Python to the SQL prompt.
Here is how to pass items to a subprocess
args = ["grep", "beans"]
child_proccess = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
child_process_output = child_proccess.communicate(b"I love beans \n I like cars")[0]
print(child_process_output)
Here's what worked:
import subprocess
import os
os.chdir("C:/sqlcl/bin")
subprocess.run(["sql",
"username/password#//database-oracle.datamore.com/moreprod.more:1521",
"#",
"C:/sqlcl/bin/test-query.sql",
";"])
Note that the query is in the same directory as the SQLCLapplication
import pexpect
from os import environ
import sys
environ['TNS_ADMIN'] = wallet
sqlcl_bin = '/sqlcl_source/sqlcl/bin/sql /nolog' # path to sqlcl bin
child = pexpect.spawn (sqlcl_bin)
child.logfile = sys.stdout.buffer
child.expect('SQL>', timeout=30)
user=
password=
service=
conn_string = f"conn {user}/{password}#{service};"
child.sendline(conn_str)
This is how I connect
Related
I am running a python script on Centos, which has some bash commands using subprocess:
import ConfigParser
import fileinput
import sys
import subprocess
config = ConfigParser.ConfigParser()
config.readfp(open(r'config.file'))
host = config.get('section-1', 'machine_hostname')
##changing the hostname of the machine
change_hostname = "sudo hostnamectl set-hostname new-hostname"
process = subprocess.Popen(change_hostname.split(),
stdout=subprocess.PIPE)
output, error = process.communicate()
I am importing the variables from a config file
how to pass the "new-hostname" as a variable "host" to the command I am executing, which could be dynamically assigned from the config file
It seems like you just want to assemble a string, you can use the format command:
change_hostname = "sudo {} set-hostname new-hostname".format(host)
should give you what you want, if you are using a fairly recent version of python(3.6.4+ iirc) you can also do:
change_hostname = f"sudo {host} set-hostname new-hostname"
I am writing a script to extract something from a specified path. I am returning those values into a variable. How can i check whether the shell command has returned something or nothing.
My Code:
def any_HE():
global config, logger, status, file_size
config = ConfigParser.RawConfigParser()
config.read('config2.cfg')
for section in sorted(config.sections(), key=str.lower):
components = dict() #start with empty dictionary for each section
#Retrieving the username and password from config for each section
if not config.has_option(section, 'server.user_name'):
continue
env.user = config.get(section, 'server.user_name')
env.password = config.get(section, 'server.password')
host = config.get(section, 'server.ip')
print "Trying to connect to {} server.....".format(section)
with settings(hide('warnings', 'running', 'stdout', 'stderr'),warn_only=True, host_string=host):
try:
files = run('ls -ltr /opt/nds')
if files!=0:
print '{}--Something'.format(section)
else:
print '{} --Nothing'.format(section)
except Exception as e:
print e
I tried checking 1 or 0 and True or false but nothing seems to be working. In some servers, the path '/opt/nds/' does not exist. So in that case, nothing will be there on files. I wanted to differentiate between something returned to files and nothing returned to files.
First, you're hiding stdout.
If you get rid of that you'll get a string with the outcome of the command on the remote host. You can then split it by os.linesep (assuming same platform), but you should also take care of other things like SSH banners and colours from the retrieved outcome.
As perror commented already, the python subprocess module offers the right tools.
https://docs.python.org/2/library/subprocess.html
For your specific problem you can use the check_output function.
The documentation gives the following example:
import subprocess
subprocess.check_output(["echo", "Hello World!"])
gives "Hello World"
plumbum is a great library for running shell commands from a python script. E.g.:
from plumbum.local import ls
from plumbum import ProcessExecutionError
cmd = ls['-ltr']['/opt/nds'] # construct the command
try:
files = cmd().splitlines() # run the command
if ...:
print ...:
except ProcessExecutionError:
# command exited with a non-zero status code
...
On top of this basic usage (and unlike the subprocess module), it also supports things like output redirection and command pipelining, and more, with easy, intuitive syntax (by overloading python operators, such as '|' for piping).
In order to get more control of the process you run, you need to use the subprocess module.
Here is an example of code:
import subprocess
task = subprocess.Popen(['ls', '-ltr', '/opt/nds'], stdout=subprocess.PIPE)
print task.communicate()
Our simple pexpect script has this:
import pexpect
import sys
test = pexpect.spawn('ftp www.today.com')
test.logfile = sys.stdout
test.expect('Name.*')
However, on the shell the script was invoked, there's no output shown.
Instead it seems to hang but we could see the process ftp ... is spawned.
How to have the output shown on the shell the script is invoked ?
thanks
Should this line:
test = pexpect.spawn('ftp www.today.com')
not be:
test = pexpect.spawn('ftp ftp.today.com')
because normally if you want ftp, you'll have to use ftp.something.com.
test.logfile will only contain the output of the command, the command line itself is not logged in the logfile attribute.
So as long as the command is spawned and that there is no output, nothing will be displayed in the shell when invoking your script.
There will be a display when for example the ftp connection timout has been reached.
You might need to use logfile_read. Here is the code:
import pexpect
import sys
test = pexpect.spawn('ftp www.today.com')
test.logfile_read = sys.stdout
test.expect('Name.*')
i have a python script on the server
#!/usr/bin/env python
import cgi
import cgitb; #cgitb.enable()
import sys, os
from subprocess import call
import time
import subprocess
form = cgi.FieldStorage()
component = form.getvalue('component')
command = form.getvalue('command')
success = True
print """Content-Type: text/html\n"""
if component=="Engine" and command=="Start":
try:
process = subprocess.Popen(['/usr/sbin/telepath','engine','start'], shell=False, stdout=subprocess.PIPE)
print "{ans:12}"
except Exception, e:
success = False
print "{ans:0}"
When I run this script and add the component and command parameters to be "Engine" and "Start" respectively - it starts the process and prints to the shell
"""Content-Type: text/html\n"""
{ans:12}
but most importantly - it starts the process!
however, when I run the script by POSTing to it, it returns {ans:12} but does not run the process which was the whole intention in the first place. Any logical explanation?
I suspect it's one of two things, firstly your process is probably running but your python code doesn't handle the output so do:
process = subprocess.Popen(['/usr/sbin/telepath','engine','start'], shell=False, stdout=subprocess.PIPE)
print process.stdout.read()
This is the most likely and explains why you see the output from the command line and not the browser, or secondly because the script is run through the browsers as the user apache and not with your userid check the permission for /usr/sbin/telepath.
#!/usr/bin/python
import os
import shutil
import commands
import time
import copy
name = 'test'
echo name
I have a simple python scripts like the above. When I attempt to execute it I get a syntax error when trying to output the name variable.
You cannot use UNIX commands in your Python script as if they were Python code, echo name is causing a syntax error because echo is not a built-in statement or function in Python. Instead, use print name.
To run UNIX commands you will need to create a subprocess that runs the command. The simplest way to do this is using os.system(), but the subprocess module is preferable.
you can also use subprocess module.
import subprocess
proc = subprocess.Popen(['echo', name],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
(out, err) = proc.communicate()
print out
Read: http://www.doughellmann.com/PyMOTW/subprocess/