From a windows application written on C++ or python, how can I execute arbitrary shell commands?
My installation of Cygwin is normally launched from the following bat file:
#echo off
C:
chdir C:\cygwin\bin
bash --login -i
From Python, run bash with os.system, os.popen or subprocess and pass the appropriate command-line arguments.
os.system(r'C:\cygwin\bin\bash --login -c "some bash commands"')
The following function will run Cygwin's Bash program while making sure the bin directory is in the system path, so you have access to non-built-in commands. This is an alternative to using the login (-l) option, which may redirect you to your home directory.
def cygwin(command):
"""
Run a Bash command with Cygwin and return output.
"""
# Find Cygwin binary directory
for cygwin_bin in [r'C:\cygwin\bin', r'C:\cygwin64\bin']:
if os.path.isdir(cygwin_bin):
break
else:
raise RuntimeError('Cygwin not found!')
# Make sure Cygwin binary directory in path
if cygwin_bin not in os.environ['PATH']:
os.environ['PATH'] += ';' + cygwin_bin
# Launch Bash
p = subprocess.Popen(
args=['bash', '-c', command],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
# Raise exception if return code indicates error
if p.returncode != 0:
raise RuntimeError(p.stderr.read().rstrip())
# Remove trailing newline from output
return (p.stdout.read() + p.stderr.read()).rstrip()
Example use:
print cygwin('pwd')
print cygwin('ls -l')
print cygwin(r'dos2unix $(cygpath -u "C:\some\file.txt")')
print cygwin(r'md5sum $(cygpath -u "C:\another\file")').split(' ')[0]
Bash should accept a command from args when using the -c flag:
C:\cygwin\bin\bash.exe -c "somecommand"
Combine that with C++'s exec or python's os.system to run the command.
Related
byte of python backup program is not working
The error I'm getting is zip command is not a recognized command on windows command prompt even after installing zip utility tool and setting the environment variables
This is the code:
import os
import time
source = ['"F:\PYTHON\byte of python code"']
target_dir = 'F:\\Backup'
target = target_dir + os.sep + time.strftime('%Y%m%d%H%M%S') + '.zip'
if not os.path.exists(target_dir):
os.mkdir(target_dir) # make directory
zip_command = "zip -r {0} ".format(target,' '.join(source))
print "Zip command is:"
print zip_command
print "Running:"
if os.system(zip_command) == 0:
print 'Successful backup to', target
else:
print 'Backup FAILED'
raw_input("Press<Enter>")
The error I'm getting is
Zip command is:
zip -r F:\Backup\20170220120316.zip
Running:
'zip' is not recognized as an internal or external command,
operable program or batch file.
Backup FAILED
Press<Enter>
Any help would be greatly appreciated. Thank you
I have a set of linux commands in a file, I am trying to execute each of them one by one in python script
for line in file:
p = subprocess.Popen(line,shell=True,stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
the above line does not execute any command as I cannot see any output.
If only the command is provided explicitly then it gets executed
cmd = "date"
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
You can use os.system or subprocess.call.
Complete code:
import os
with open("/path/to/file") as file:
command = file.readlines()
for line in command:
p = str(os.system(str(line)))
The syntax is
import os
os.system("path/to/executable option parameter")
or
os.system("executable option paramter")
For example,
os.system("ls -al /home")
or part of code(with subprocess):
for line in file:
subprocess.call(line, shell=True)
I got this info at https://docs.python.org/2/library/subprocess.html
NOTE: os.system is deprecated but it still works
Try after removing shell=True, My command was also facing same problem when I was executing this:
subprocess.Popen(
["python3", os.path.join(script_dir, script_name)] + list(args),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=script_dir,
shell=True
)
but once I remove shell it worked properly.
is there eval function? I've read "help" and I didnt find
I want to make eval("gdb command")
because I want to create my own function for grepping using this method
How to grep on gdb print.
I want to make eval($arg1)
There is an eval command, but it doesn't really do what you want. It provides a limited form of substitution of values into commands.
For a command along the lines of grep, I would suggest writing it in Python. This would be relatively easy to do. The idea would be to use gdb.execute to capture the output of a command into a string, and then use Python to search the string however you like. If done from Python you have complete control of how to parse the command-line, something that's not true if you use the gdb define command.
Oddly enough, I wrote a grep python gdb function earlier today for another question. These couple of files make a new command that checks if the call stack contains _malloc. This should be a pretty good start for other string searching and evaluation functions.
Here is a script for gdb
# gdb script: pygdb-logg.gdb
# easier interface for pygdb-logg.py stuff
# from within gdb: (gdb) source -v pygdb-logg.gdb
# from cdmline: gdb -x pygdb-logg.gdb -se test.exe
# first, "include" the python file:
source -v pygdb-logg.py
# define shorthand for inMalloc():
define inMalloc
python inMalloc()
end
Here is the python file:
#!/usr/bin/python
# gdb will 'recognize' this as python
# upon 'source pygdb-logg.py'
# however, from gdb functions still have
# to be called like:
# (gdb) python print logExecCapture("bt")
import sys
import gdb
import os
def logExecCapture(instr):
# /dev/shm - save file in RAM
ltxname="/dev/shm/c.log"
gdb.execute("set logging file "+ltxname) # lpfname
gdb.execute("set logging redirect on")
gdb.execute("set logging overwrite on")
gdb.execute("set logging on")
gdb.execute("bt")
gdb.execute("set logging off")
replyContents = open(ltxname, 'r').read() # read entire file
return replyContents
# in malloc?
def inMalloc():
isInMalloc = -1;
# as long as we don't find "Breakpoint" in report:
while isInMalloc == -1:
REP=logExecCapture("n")
#Look for calls that have '_malloc' in them
isInMalloc = REP.find("_malloc")
if(isInMalloc != -1):
# print ("Malloc:: ", isInMalloc, "\n", REP)
gdb.execute("set $inMalloc=1")
return True
else:
# print ("No Malloc:: ", isInMalloc, "\n", REP)
gdb.execute("set $inMalloc=0")
return False
I am having difficulties running a series of sequential commands using the subprocess module, i need to do this so a python program can call in an installation of a cv virtualenv and then run another python program (that needs to be run within the virtualenv)
This is the command string i run from terminal, you can see it contains multiple commands that run in sequence until the creation of the cv virtual env:
sudo pip install virtualenv virtualenvwrapper && sudo rm -rf ~/.cache/pip && export WORKON_HOME=$HOME/.virtualenvs && source /usr/local/bin/virtualenvwrapper.sh && source ~/.bashrc && mkvirtualenv cv
Running this in the terminal returns me something like this:
(cv) name#computer:~$
from that i can run my python scripts that need the openCV
my code so far is this:
from subprocess import Popen, PIPE, STDOUT
cmd1 = 'sudo pip install virtualenv virtualenvwrapper'
cmd2 = 'sudo rm -rf ~/.cache/pip'
cmd3 = 'export WORKON_HOME=$HOME/.virtualenvs'
cmd4 = 'source /usr/local/bin/virtualenvwrapper.sh'
cmd5 = 'source ~/.bashrc'
cmd6 = 'mkvirtualenv cv'
cmd7 = 'cd /script path'
cmd8 = 'python novo.py'
final = Popen("{}; {}; {}; {}; {}; {}; {}; {}".format(cmd1, cmd2,cmd3, cmd4, cmd5, cmd6, cmd7, cmd8), shell=True, stdin=PIPE,
stdout=PIPE, stderr=STDOUT, close_fds=True)
stdout, nothing = final.communicate()
log = open('log', 'w')
log.write(stdout)
log.close()
And the errors in log look like this:
/bin/sh: 1: source: not found
/bin/sh: 1: source: not found
/bin/sh: 1: mkvirtualenv: not found
How can i achieve a terminal like execution ?
again, sequence is crucial.
/bin/sh: 1: source: not found
shell=True uses /bin/sh by default. source shell builtin hints at bash. Pass executable='/bin/bash'.
btw, you could use a multiline string literal:
#!/usr/bin/env python3
import sys
from subprocess import check_call, DEVNULL, STDOUT
with open('log', 'wb', 0) as file:
check_call("""set -e -x
{python} -mpip install --user virtualenv virtualenvwrapper
rm -rf ~/.cache/pip
export WORKON_HOME=$HOME/.virtualenvs
source /path/to/virtualenvwrapper.sh
source ~/.bashrc
mkvirtualenv cv
cd /script path
{python} novo.py
""".format(python=sys.executable),
shell=True, executable='/bin/bash',
stdin=DEVNULL, stdout=file, stderr=STDOUT, close_fds=True)
Or save the command into a separate bash script and run the script instead.
DEVNULL is Python 3 feature—it is easy to emulate it on Python 2 too: DEVNULL = open(os.devnull, 'r+b', 0).
I use this command on the Linux terminal to perform a function on a file ./pythonfile.py --count ../textfile.txt
now I use that command on windows on command prompt and it doesn't work.
I use python pythonfile.py --count ./textfile.txt to read and count the text after every white space .
When I press enter it gives the error.
error is : IOError: [Errno 2] NO such file or directory: '--count'
import sys
def cat(filename):
f=open(filename,'rU')
text=f.read()
print text
f.close()
def main():
cat(sys.argv[1])
if __name__=="__main__":
main()
You should get the same error on Linux. You can inspect sys.argv with:
print(sys.argv)
It prints:
['pythonfile.py', '--count', './textfile.txt']
Use sys.argv[2] to get to your file name:
def main():
print(sys.argv)
cat(sys.argv[2])
This should work on Windows too.