Run program using cmd on remote Windows machine - python

I want to create a Python script that opens a cmd in remote Windows machine using psexec, and runs my_program.exe from this cmd, and when some event occurs it sends Ctrl+c to my_program.exe which handles this signal somehow.
Here's my code:
from os import chdir, path
from subprocess import Popen, PIPE
psexec_dir = r'C:\Users\amos1\Downloads\PSTools'
chdir(psexec_dir)
path.join(psexec_dir, 'psexec.exe')
command = ['psexec.exe', '\\amos', 'cmd']
p = Popen(command, stdin = PIPE, stdout = PIPE)
p.stdin.write(b'my_program.exe\r\n')
while True:
if some_condition:
ctrl_c = b'\x03'
p.stdin.write(ctrl_c)
break
for line in p.stdout.readlines():
print(line)
p.kill()
The problems:
my_program.exe does not run
p.kill raises WindowsError: [Error 5] Access is denied (even though I used the answers from here and did both chdir and path.join in my code)
Notice that both my computer and the target computer are Windows machines

Related

Why do tmux and vim print garbage in my SSH wrapper script?

I have written an SSH wrapper script that does local line editing. It is invoked similarly to SSH. For example: python3 sshwrapper.py user#example.com -CX. The problem is that when I connect to a remote computer using this script and use vim or tmux there, some garbage is printed. This problem is not specific to SSH, since the problems also appear when I use this script to wrap bash instead of ssh.
Examples:
After starting tmux, some garbage is printed after the bash prompt:
abc#me:~$ ^[[?65;1;9c
When opening a new file in Vim using vim mynewfile.txt, this appears on the first line:
^[[2;2R^[[>65;6003;1c^[]10;rgb:0000/0000/0000^G^[]11;rgb:ffff/ffff/dddd^G
How do I fix the problem?
This is the script in question:
import os
import pty
import select
import signal
import subprocess
import sys
master_fd, slave_fd = pty.openpty()
process = subprocess.Popen(['ssh'] + sys.argv[1:],
stdin=slave_fd,
stdout=slave_fd,
stderr=subprocess.STDOUT,
# Important for Ctrl-c in the remote terminal.
preexec_fn=os.setsid)
def sigint_handler(_signum, _frame):
os.write(master_fd, b'\03') # Send Ctrl-c.
signal.signal(signal.SIGINT, sigint_handler)
def sigtstp_handler(_signum, _frame):
os.write(master_fd, b'\x1A') # Send Ctrl-z.
signal.signal(signal.SIGTSTP, sigtstp_handler)
def sigchld_handler(_signum, _frame):
process.wait()
sys.exit(process.returncode)
signal.signal(signal.SIGCHLD, sigchld_handler)
while process.poll() is None:
# Block until there is something to read or write.
r, w, e = select.select([sys.stdin, master_fd], [], [])
if sys.stdin in r:
# Write to SSH.
user_input = os.read(sys.stdin.fileno(), 4096)
if not user_input:
os.write(master_fd, b'\04') # Send Ctrl-d.
else:
os.write(master_fd, user_input)
if master_fd in r:
# Read from SSH.
data = os.read(master_fd, 4096)
sys.stdout.write(data.decode())
sys.stdout.flush()
I am using Python 3.8.10 on Ubuntu 20.04 on both my local computer and the remote computer. This is a self-education project, so I am writing the program using Python standard libraries only.
There is a bad hack you can try. After ssh into the machine try removing env variable LS_COLORS
export LS_COLORS=none
This change will persist in your session.
In your bashrc:
alias tmux="TERM=screen-256color-bce tmux"
In your .tmux.conf:
set -g default-terminal "xterm-256color"
Try to run your script from a different terminal application (preferably set to the defaults) and see if you still have the problem.

Use python to launch programm in 'terminal mode' and add commands

I use the subprocess module to launch a programm in "terminal mode" by adding a flag after the executable like this:
subprocess.call(nuke + " -t ")
This results in the terminal mode, so all following commands are in the context of the programm (my guess is that it is the programms python interpreter).
Nuke 11.1v6, 64 bit, built Sep 8 2018. Copyright (c) 2018 The Foundry Visionmongers Ltd. All Rights Reserved. Licence expires on: 2020/3/15
>>>
How can I keep pushing commands to the interpreter from my python script that launched the terminal mode?
How would you quit this programms interpreter from the script?
EDIT:
nuketerminal = subprocess.Popen(nuke + " -t " + createScript)
nuketerminal.kill()
terminates the process before the python interpreter is loaded and the script is executed any idea on how to solve this elegantly without a delay?
from subprocess import Popen, PIPE
p = subprocess.Popen([nuke, "-t"], stdin=PIPE, stdout=PIPE) # opens a subprocess
p.stdin.write('a line\n') # writes something to stdin
line = p.stdout.readline() # reads something from the subprocess stdout
Not syncing reads and writes may cause a deadlock, f.e. when both your main process and subprocess will wait for input.
You can wait for the subprocess to end:
return_code = p.wait() # waits for the process to end and returns the return code
# or
stdoutdata, stderrdata = p.communicate("input") # sends input and waits for the subprocess to end, returning a tuple (stdoutdata, stderrdata).
Or you can end the subprocess with:
p.kill()

How to exit cleanly with tcpdump running in subprocess in sudo mode

I am running tcpdump using the subprocess module in python to capture a trace of a website, using this piece of code:
import subprocess
from tbselenium.tbdriver import TorBrowserDriver
site = "check.torproject.org"
try:
process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', 'eth0', '-w', 'trace.pcap'], stdout=subprocess.PIPE)
with TorBrowserDriver("/path/to/tor-browser_en-US/") as driver:
driver.load_url("https://" + site, wait_on_page=20)
process.send_signal(subprocess.signal.SIGTERM)
except OSError:
print "OSError"
The code gives me an OSError and when I try to open the pcap file in wireshark I get the following error box:
The capture file appears to have been cut short in the middle of a packet.
I've read this solution to the same issue, and have tried sending both a SIGINT and a SIGTERM, but I get the same truncated-packet message in each case along with an OSError. I have also tried using process.terminate() but that doesn't work either. Is there any way I could make tcpdump exit cleanly while running in sudo mode. Thanks!
As the OSError: [Errno 1] Operation not permitted suggest, killing the process is not permitted. Because you used sudo, killing the process should be instantiated sudo as well. Maybe you try this:
import subprocess
import os
from tbselenium.tbdriver import TorBrowserDriver
site = "check.torproject.org"
try:
process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', 'eth0', '-w', 'trace.pcap'], stdout=subprocess.PIPE)
with TorBrowserDriver("/path/to/tor-browser_en-US/") as driver:
driver.load_url("https://" + site, wait_on_page=20)
cmd = "sudo kill " + str(process.pid)
os.system(cmd)
except OSError, e:
print e
Since tcpdump needs su privileges you can simply run the script as su and check for it before you spawn tcpdump:
# Check we are running as root:
if os.geteuid() != 0:
print('This script requires root privileges to capture packets. Try running this script as root.')
raise SystemExit
# Start TCPDUMP
import subprocess, os
_process = subprocess.Popen(['tcpdump', '-nnvvv', '-s0', '-w', os.path.join('/tmp', 'output.pcap'), ])
This way you can run
_process.terminate()
or
_process.kill()
to send the proper signal to tcpdump

Execute process from the windows command line in Python

I would like to know how to execute this java process using the windows command line, from inside Python 2.7 on Windows 8.
I thought I had already solved this problem, but I recently changed computers from Windows 7 to Windows 8 and my code stopped working. I have confirmed that the windows command used in the script below executes properly when run directly from cmd.exe
import os
import subprocess
def FileProcess(inFile):
#Create the startup info so the java program runs in the background (for windows computers)
startupinfo = None
if os.name == 'nt':
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
#Execute Stanford Core NLP from the command line
print inFile
cmd = ['java', '-Xmx1g','-cp', 'stanford-corenlp-1.3.5.jar;stanford-corenlp-1.3.5-models.jar;xom.jar;joda-time.jar', 'edu.stanford.nlp.pipeline.StanfordCoreNLP', '-annotators', 'tokenize,ssplit,pos,parse', '-file', inFile]
output = subprocess.call(cmd, startupinfo=startupinfo)
print inFile[(str(inFile).rfind('\\'))+1:] + '.xml'
outFile = file(inFile[(str(inFile).rfind('\\'))+1:] + '.xml')
FileProcess("C:\\NSF_Stuff\\ErrorPropagationPaper\\RandomTuftsPlain\\PreprocessedTufts8199PLAIN.txt")
When this code is executed, I receive the error message that the output file does not exist. The java process I am executing should output an xml file when it is done.
It is my belief that for some reason subprocess.call is never successfully executing the command. I have tried using subprocesss.popen for the same task and I get the same results.
EDIT: I have changed my code so that I can capture error messages and I think I am beginning to understand the problem.
I changed my code to
import os
import subprocess
def FileProcess(inFile):
#Create the startup info so the java program runs in the background (for windows computers)
startupinfo = None
if os.name == 'nt':
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
#Execute Stanford Core NLP from the command line
print inFile
cmd = ['java', '-Xmx1g','-cp', 'stanford-corenlp-1.3.5.jar;stanford-corenlp-1.3.5-models.jar;xom.jar;joda-time.jar', 'edu.stanford.nlp.pipeline.StanfordCoreNLP', '-annotators', 'tokenize,ssplit,pos,parse', '-file', inFile]
proc = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True)
print proc
stdoutdata, stderrdata = proc.communicate()
print stdoutdata
print stderrdata
outFile = file(inFile[(str(inFile).rfind('\\'))+1:] + '.xml')
FileProcess("C:\\NSF_Stuff\\ErrorPropagationPaper\\RandomTuftsPlain\\PreprocessedTufts8199PLAIN.txt")
stdoutdata contains the message "'java' is not recognized as an internal or external command, operable program or batch file."
Now this is a very bizarre message because java is definitely a recognized command when I run it from the cmd.exe . There is some issue here where executing the command from python is messing with my system environment variables such that java is no longer recognized as a command.
I was able to solve my problem by adding the location of java to my PATH variable. Apparently java wasn't in my path variable. I didn't even bother checking this originally because I was having no problems executing java commands from the windows command line. I'm guessing that commands executed directly from cmd.exe use a different environment variable to find the java executable than commands executed indirectly from the subprocess module.
By trying your code it prints out PreprocessedTufts8199PLAIN.txt.xml file name. I'm not sure if the .txt.xml extension was the desired result. If your file has only .xml extension, then you're not stripping away the original .txt header.
Try to change this line:
outFile = file(inFile[(str(inFile).rfind('\\'))+1:] + '.xml')
Into this code:
fnameext = inFile[(str(inFile).rfind('\\'))+1:]
fname,fext = os.path.splitext(fnameext)
xmlfname = fname + '.xml'
xmlfpath = os.path.join(".", xmlfname)
print "xmlfname:", xmlfname, " xmlfpath:", xmlfpath
print "current working directory:", os.getcwd()
outFile = open(xmlfpath, "r")
Answer for extension stripping.

Subprocess is not invoking my command(or is doing it wrong)

Overview:
I have an application that sometimes must make something with celery- and if it is simple task such as count something- everything is ok.
I' ve got one task which must convert existing file to another file using MS Windows program. So- I installed WINE, then installed application and added folowing task to my tasks.py:
def convert_file( fil, to_format = 'pdf', save_to = '/tmp', callback = None ):
devnull = open( '/dev/null', 'w' )
commands = "xvfb-run -a wine '[ABSOLUTE_PATH_TO_WINDOWS_APP]' /r /f 104 %s" % fil
p = subprocess.Popen( commands, shell=True, cwd='/home/test', env=os.environ, stdout = devnull, stderr = subprocess.STDOUT )
p.wait()
devnull.close()
if callback:
subtask( callback ).delay( )
else:
return outfile
Problem:
The command isn't called or is called but nothing is happening(there isn't new file anywhere in filesystem)- but if I'll call this command from bash or from interactive python shell, everything is ok.
Edit:
When I'm calling the command from command line I get this:
test#ubuntu:~$ xvfb-run -a /home/test/.wine/....exe /r /f 104 /home/test/fs/...
err:winediag:X11DRV_WineGL_InitOpenglInfo The Mesa OpenGL driver is using software rendering, most likely your OpenGL drivers haven't been installed correctly
test#ubuntu:~$ XIO: fatal IO error 11 (Zasoby chwilowo niedostępne) on X server ":99"
after 1262 requests (1226 known processed) with 0 events remaining.
[Here i must press enter]
test#ubuntu:~$
Use
p = subprocess.Popen( commands, shell=True, cwd='/home/test', env=os.environ, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
for your Popen command, then
print p.communicate()
p.wait()
print p.communicate()
To see what it prints to stdout and stderr and figure out what you're doing wrong.
Edit: Xvfb is a fake framebuffer; it doesn't have hardware acceleration. Try changing your wine settings not to require hardware acceleration / not to use OpenGL / to do software rendering with winecfg.

Categories

Resources