Python Program Correction - python

I need help I am trying to open the terminal and type ifconfig and enter then read the output on a mac then il transition this later to kali but I am getting a error with the file path to terminal and I cant start it, here is my code.
import os,sys
#opens terminal
terminal = os.open('/Applications/Utilities/Terminal.app', os.O_RDWR|os.O_APPEND)
#writes ifconfig
os.write(terminal, 'ifconfig')
os.close(terminal)

I suggest you use subprocess
import subprocess
def popen(executable):
sb = subprocess.Popen(
'%s' % executable,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = sb.communicate()
return stdout, stderr, sb.returncode
you can pass ifconfig to this method and it will execute the command and return the output for you.

I agree with using subprocess. To add to Amin's answer, for something this simple that you just want the output from:
import subprocess
print(subprocess.check_output(['ifconfig']))
Edit:
What I was talking about in my comment is the new run function that returns a CompletedProcess class that holds all the relevant information for you. That way you no longer have to have three different variables holding your stdout, sterr and returncode.

Related

Python Popen, OS, Commands all return nothing when running a command in linux

So I need to get the version of something on a client and when I try to use Popen, Call, Check_Call, OS, Commands it all returns a value of nothing. When I run the script on a system in putty it returns me an empty line. Can it be because of putty?. Running on Linux, CentOS if that makes any difference. Thank you guys ahead of time.
def getJavacVer():
p = sp.Popen("javac -version", stdout=sp.PIPE, shell=True)
(output, err) = p.communicate()
print output
The javac program returns the -version output through stderr, so stderr argument of Popen also need to be passed. Try:
>>> from subprocess import Popen
>>> from subprocess import PIPE
>>> p = Popen(['javac', '-version'], stdout=PIPE, stderr=PIPE)
>>> p.communicate()
(b'', b'javac 1.8.0_171\n')
The second element is of the result is the captured output of the stderr stream, which contains the version number.
This will only work on *nix:
import commands
print commands.getstatusoutput('javac -version')
Thank you to the few fellas that answered the question. The output is being put out to stderr instead of stdout. Thank you to everyone

Popen with Context Managers

I have been trying to write a function which would execute a command passed to it thru a parameter using POPEN along with Context Managers. Unfortunately, I am unable to get it to work. Can someone please help?
import os
import sys
import subprocess
import inspect
def run_process(cmd_args):
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as proc:
log.write(proc.stdout.read())
run_process("print('Hello')")
The output expected is "Hello". Can someone please point out where I am going wrong?
What you have done is right if you are running a bash command through the subprocess.
Inside the context manager "with ..." what you have done is to reading out the output from the terminal and storing them as byte(s) in "output" variable and trying to print out the bytes in ASCII after decoding it.
Try returning the value from the context manager and then decode it in the calling function:
import os
import sys
import subprocess
import inspect
def run_process(cmd_args): # Below added shell=True' in parameters.
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc:
return proc.stdout.read() # returns the output
# Optionally you can use the 'encoding='utf-8' argument
# instead and just print(proc.stdout.read()).
print(run_process().decode('utf-8'))
I was having a similar issue while pipelining a process to another program and I did the decoding in the other program and surprisingly it worked. Hope it works for you as well.
def run_process(cmd_args):
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as p:
output = p.stdout.read()
return output
It worked for the same question.
Popen runs the command it receives as you would run something in your terminal (example: CMD on Windows or bash on Linux). So, it does not execute Python, but Bash code (on Linux for ex). The Python binary has a command, -c that does what you would need: executes a Python command right away. So you have to options:
either use echo Hello (works on Windows or Linux too, echo it's both
in batch and in bash)
or you could use python -c "print('Hello') instead of just the print command.
Without making too many changes to your existing script, I have edited your script with the below comments indicating what I did to get it to work. I hope this helps.
import os
import sys
import subprocess
import inspect
def run_process(cmd_args): # Below added shell=True' in parameters.
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc:
output = proc.stdout.read() # Reads the output from the process in bytes.
print(output.decode('utf-8')) # Converts bytes to UTF-8 format for readability.
# Optionally you can use the 'encoding='utf-8' argument
# instead and just print(proc.stdout.read()).
run_process("echo Hello") # To display the message in the prompt use 'echo' in your string like this.
Note: Read the Security Considerations section before using shell=True.
https://docs.python.org/3/library/subprocess.html#security-considerations

Python get script output with now only the pid of file

for example I run a script
os.execv('script.py',('',))
As I read in docs this command starts a script from your current script by taking it's pid and reasigning it to run script.py. So I can get the pid of process.
The question is following:
After running execv I need to get the stdout of this script, and the only thing I know is the pid of process. Is it possible to perform this with python ? Any suggestions ? I need to use only execv()
Another possible solution redirecting the output to a file.
import os,sys
sys.stdout = open("./data.out","w")
os.dup2(sys.stdout.fileno(), 1)
os.execv('/usr/bin/python', ['python', './script.py'])
os.execv is just binding to execve system call. Thing that you need is a subprocess module:
import sys
import subprocess
proc = subprocess.Popen([sys.executable, 'script.py'],
stdout = subprocess.PIPE)
proc.wait()
print(proc.stdout.read())
See https://docs.python.org/2/library/subprocess.html

How to execute a command prompt command from python

I tried something like this, but with no effect:
command = "cmd.exe"
proc = subprocess.Popen(command, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
proc.stdin.write("dir c:\\")
how about simply:
import os
os.system('dir c:\\')
You probably want to try something like this:
command = "cmd.exe /C dir C:\\"
I don't think you can pipe into cmd.exe... If you are coming from a unix background, well, cmd.exe has some ugly warts!
EDIT: According to Sven Marnach, you can pipe to cmd.exe. I tried following in a python shell:
>>> import subprocess
>>> proc = subprocess.Popen('cmd.exe', stdin = subprocess.PIPE, stdout = subprocess.PIPE)
>>> stdout, stderr = proc.communicate('dir c:\\')
>>> stdout
'Microsoft Windows [Version 6.1.7600]\r\nCopyright (c) 2009 Microsoft Corporatio
n. All rights reserved.\r\n\r\nC:\\Python25>More? '
As you can see, you still have a bit of work to do (only the first line is returned), but you might be able to get this to work...
Try:
import os
os.popen("Your command here")
Using ' and " at the same time works great for me (Windows 10, python 3)
import os
os.system('"some cmd command here"')
for example to open my web browser I can use this:
os.system(r'"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"')
(Edit)
for an easier way to open your browser I can use this:
import webbrowser
webbrowser.open('website or leave it alone if you only want to open the
browser')
Try adding a call to proc.stdin.flush() after writing to the pipe and see if things start behaving more as you expect. Explicitly flushing the pipe means you don't need to worry about exactly how the buffering is set up.
Also, don't forget to include a "\n" at the end of your command or your child shell will sit there at the prompt waiting for completion of the command entry.
I wrote about using Popen to manipulate an external shell instance in more detail at: Running three commands in the same process with Python
As was the case in that question, this trick can be valuable if you need to maintain shell state across multiple out-of-process invocations on a Windows machine.
Taking some inspiration from Daren Thomas's answer (and edit), try this:
proc = subprocess.Popen('dir C:\\', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = proc.communicate()
out will now contain the text output.
They key nugget here is that the subprocess module already provides you shell integration with shell=True, so you don't need to call cmd.exe directly.
As a reminder, if you're in Python 3, this is going to be bytes, so you may want to do out.decode() to convert to a string.
Why do you want to call cmd.exe ? cmd.exe is a command line (shell). If you want to change directory, use os.chdir("C:\\"). Try not to call external commands if Python can provide it. In fact, most operating system commands are provide through the os module (and sys). I suggest you take a look at os module documentation to see the various methods available.
It's very simple. You need just two lines of code with just using the built-in function and also it takes the input and runs forever until you stop it. Also that 'cmd' in quotes, leave it and don't change it. Here is the code:
import os
os.system('cmd')
Now just run this code and see the whole windows command prompt in your python project!
Here's a way to just execute a command line command and get its output using the subprocess module:
import subprocess
# You can put the parts of your command in the list below or just use a string directly.
command_to_execute = ["echo", "Test"]
run = subprocess.run(command_to_execute, capture_output=True)
print(run.stdout) # the output "Test"
print(run.stderr) # the error part of the output
Just don't forget the capture_output=True argument and you're fine. Also, you will get the output as a binary string (b"something" in Python), but you can easily convert it using run.stdout.decode().
In Python, you can use CMD commands using these lines :
import os
os.system("YOUR_COMMAND_HERE")
Just replace YOUR_COMMAND_HERE with the command you like.
From Python you can do directly using below code
import subprocess
proc = subprocess.check_output('C:\Windows\System32\cmd.exe /k %windir%\System32\\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f' ,stderr=subprocess.STDOUT,shell=True)
print(str(proc))
in first parameter just executed User Account setting you may customize with yours.

How to redirect the output of .exe to a file in python?

In a script , I want to run a .exe with some command line parameters as "-a",and then
redirect the standard output of the program to a file?
How can I implement that?
You can redirect directly to a file using subprocess.
import subprocess
with open('output.txt', 'w') as output_f:
p = subprocess.Popen('Text/to/execute with-arg',
stdout=output_f,
stderr=output_f)
Easiest is os.system("the.exe -a >thefile.txt"), but there are many other ways, for example with the subprocess module in the standard library.
You can do something like this
e.g. to read output of ls -l (or any other command)
p = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE)
print p.stdout.read() # or put it in a file
you can do similar thing for stderr/stdin
but as Alex mentioned if you just want it in a file, just redirect the cmd output to a file
If you just want to run the executable and wait for the results, Anurag's solution is probably the best. I needed to respond to each line of output as it arrived, and found the following worked:
1) Create an object with a write(text) method. Redirect stdout to it (sys.stdout = obj). In your write method, deal with the output as it arrives.
2) Run a method in a seperate thread with something like the following code:
p = subprocess.Popen('Text/to/execute with-arg', stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=False)
while p.poll() is None:
print p.stdout.readline().strip()
Because you've redirected stdout, PIPE will send the output to your write method line by line. If you're not certain you're going to get line breaks, read(amount) works too, I believe.
3) Remember to redirect stdout back to the default: sys.stdout = __sys.stdout__
Although the title (.exe) sounds like it's a problem on Windows.
I had to share that the accepted answer (subprocess.Popen() with stdout/stderr arguments) didn't work for me on Mac OS X (10.8) with python 2.7.
I had to use subprocess.check_output() (python 2.7 and above) to make it work. Example:
import subprocess
cmd = 'ls -l'
out = subprocess.check_output(cmd, shell=True)
with open('my.log', 'w') as f:
f.writelines(out)
f.close()
Note that this solution writes all the accumulated output out when the program finishes.
If you want to monitor the log file during the run. You may want to try something else.
In my own case, I only cared about the end result.

Categories

Resources