Run bash command in Cygwin from another application - c++

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 on Windows System

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

Subprocess popen not executing the command

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.

debugger gdb evaluate expression

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

Running shell commands sequentially in one shell with subprocess

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).

How to do function on readfile on command prompt in Python (on Windows)

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.