How to keep subprocess powershell session going throughout python - python

I am building an email purge tool. The premise is that the .py needs to connect to the IPPSSession using Powershell. like so:
sp.run(f"Connect-IPPSSession -UserPrincipalName {Email}", shell=True)
However, when I go running the commands later in the program, it does not recognize the commands.
From what I have read, it appears (subprocess) sp.run is connecting and promptly disconnecting.
For the commands later in the program to be recognized, I need to maintain a connection.
Is there a way to have the IPPSSession run the entire length of the program? I guess I could rewrite the whole program in PowerShell exclusively....

After some stimulants and quite a bit of thinking. I found a better way to format the query. Behold:
Email_Purge = f"Connect-IPPSSession -UserPrincipalName {Email} ; New-ComplianceSearchAction -SearchName {Search_Name!r} -purge -PurgeType {Purge_Type}"
if Purge_Type == "SoftDelete" or Purge_Type == "HardDelete":
sp.run(Email_Purge, shell=True)
else:
print("Please enter [SoftDelete] or [HardDelete]")
The session runs the whole length of the Var. so all of the input happens first, and then it executes and breaks the session cleanly.

Related

Is there any way to delay a Python Script till an Application is running?

I want the Python Code to open Notepad and let the user type in it, by the time it should not execute the rest of the code. After I close notepad, it should resume the script from where it left. Is there any way to do this? Or should I try a different approach?
What have I Tried:
Here is the code so far -
with open('file.txt','w') as file: #this is to create an empty file
file.close()
pass
os.startfile('file.txt')
time.sleep() # what value should I enter for time.sleep? or is there a module to do this?
I possibly can run a while loop to check whether the notepad.exe is running or not, if it is, if it's not, it should break out of the loop and execute the rest of the code.However, the problem is how do I check if notepad.exe is running?
Running a while loop to delete the file, if it get's an error, means the program is still running, but the problem is if it does not get the error, It will delete the file.
It would be better, if when launching of the program, it takes the process ID of it, and only wait for it to terminated. So that other instances of notepad won't be affected.
From the docs:
startfile() returns as soon as the associated application is
launched. There is no option to wait for the application to close, and
no way to retrieve the application’s exit status.
If you know the path of the application to open the file with, you could use subprocess.Popen() which allows for you to wait.
p = subprocess.Popen([
'C:\\Windows\\System32\\notepad.exe',
'path\\to\\file'
])
(output, err) = p.communicate()
#This makes the wait possible
p_status = p.wait()
See:
http://docs.python.org/library/os.html#os.startfile
http://docs.python.org/library/subprocess.html#subprocess.Popen

How to end a python subprocess with no return?

I'm working on a BCP wrapper method in Python, but have run into an issue invoking the command with subprocess.
As far as I can tell, the BCP command doesn't return any value or indication that it has completed outside of what it prints to the terminal window, which causes subprocess.call or subprocess.run to hang while they wait for a return.
subprocess.Popen allows a manual .terminate() method, but I'm having issues getting the table to write afterwards.
The bcp command works from the command line with no issues, it loads data from a source csv according to a .fmt file and writes an error log file. My script is able to dismount the file from log path, so I would consider the command itself irrelevant and the question to be around the behavior of the subprocess module.
This is what I'm trying at the moment:
process = subprocess.Popen(bcp_command)
try:
path = Path(log_path)
sleep_counter = 0
while path.is_file() == False and sleep_counter < 16:
sleep(1)
sleep_counter +=1
finally:
process.terminate()
self.datacommand = datacommand
My idea was to check that the error log file has been written by the bcp command as a way to tell that the process had finished, however while my script no longer freezes with this, and the files are apparently being successfully written and dismounted later on in the script. The script terminates in less than the 15 seconds that the sleep loop would use to end it as well.
When the process froze my Spyder shell (and Idle, so it's not the IDE), I could force terminate it by closing the console itself and it would write to the server at least.
However it seems like by using the .terminate() the command isn't actually writing anything to the server.
I checked if a dumb 15 second time-out (it takes about 2 seconds to do the BCP with this data) would work as well, in case it was writing an error log before the load finished.
Still resulted in an empty table on SQL server.
How can I get subprocess to execute a command without hanging?
Well, it seems to be a more general issue about calling helper functions with Popen
as seen here:
https://github.com/dropbox/pyannotate/issues/67
I was able to fix the hanging issue by changing it to:
subprocess.Popen(bcp_command, close_fds = True)

BaseHTTPServer socket close after python script exit

I already searched for solutions to my questions and found some, but they don't work for me or are very complicated for what I want to achieve.
I have a python (2.7) script that creates 3 BaseHTTPServers using threads. I now want to be able to close the python script from itself and restart it. For this, I create an extra file called "restart_script" with this content:
sleep 2
python2 myScript.py
I then start this script and after that, close my own python script:
os.system("nohup bash restart_script & ")
exit()
This works quite well, the python script closes and the new one pops up 2 seconds later, but the BaseHTTPServers do not come up, the report that the Address is already in use. (socket.error Errno 98).
I initiate the server with:
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
Then I let it serve forever:
thread.start_new_thread(httpd.serve_forever, tuple())
I alternatively tried this:
httpd_thread = threading.Thread(target=httpd.serve_forever)
httpd_thread.daemon = True
httpd_thread.start()
But this has the same result.
If I kill the script using strg+c and then start it right again right after that, everything works fine. I think as long as I want to restart the script from its own, the old process is still somehow active and I need to somehow disown it so that the sockets can be cleared.
I am running on Linux (Xubuntu).
How can I really really kill my own script and then bring it up again seconds later so that all sockets are closed?
I found an answer to my specific problem.
I just use another script which starts my main program using os.system(). If the script wants to restart, I just close it regularly and the other script just starts it again, over and over...
If I want to actually close my script, I add a file and check in the other script if this file exists..
The restart-helper-script looks like this:
import os, time
cwd = os.getcwd()
#first start --> remove shutdown:
try:
os.remove(os.path.join(cwd, "shutdown"))
except:
pass
while True:
#check if shutdown requested:
if os.path.exists(os.path.join(cwd, "shutdown")):
break
#else start script:
os.system("python2 myMainScript.py")
#after it is done, wait 2 seconds: (just to make sure sockets are closed.. might be optional)
time.sleep(2)

ssh connection handle pexpect in python

I was trying to automate a system where we have a linux box but customized.. to go to shell we have to pass some input. like below:
tanuj$ ssh admin#10.10.10.10
Used by Tanuj
Password:
command line interface
app > en
app # config t
app (config) #
I have written a script using pexpect in python. I am able to login and execute the command
pexpect.sendline("ls -lrt")
pexpect.expect("#")
but when i am using pexpect.before() .. is getting nothing .. when the command output is long and also i could see the pexpect.before has also got the command in it.
any idea how to solve this.. or is there any other python module which i can use to automation a ssh session like i have here.
i also tried using paramiko but it did not work because we have a to execute some commands before we can reach to normal shell prompt.
I am also facing the similar problem. I was about to ask the question. You are using a # sign in your
pexpect.expect('#')
This # sign comments everything written after it. Further I guess you should create a child process to spawn a process, Like(I don't know if I'm right in your situation):
child=pexpect.spawn('ssh admin#10.10.10.10')
child.expect('prompt_expected_by_you') # put in the prompt you expect after sending SSH
child.sendline('your_password')
child.expect('Prompt_expected_by_you')
child.sendline('ls -ltr')
child.expect('Prompt_expected_by_you')
print child.before, # , will keep continue your newline print
print child.after
child.sendline('exit')
child.expect('Prompt_expected_by_you')
child.sendline('exit')
child.expect('Prompt_expected_by_you') # may not be required
child.close # close the child session
I have successfully used these commands in FTP, but not able to print result of 'LS -LTR' in SSH. I guess i'll have to initiate a shell, but not sure. Any progress on your side?
Could someone help???

Python and subprocess input piping

I have a small script that launches and, every half hour, feeds a command to a java program (game server manager) as if the user was typing it. However, after reading documentation and experimenting, I can't figure out how I can get two things:
1) A version which allows the user to type commands into the terminal windoe and they will be sent to the server manager input just as the "save-all" command is.
2) A version which remains running, but sends any new input to the system itself, removing the need for a second terminal window. This one is actually half-happening right now as when something is typed, there is no visual feedback, but once the program is ended, it's clear the terminal has received the input. For example, a list of directory contents will be there if "dir" was typed while the program was running. This one is more for understanding than practicality.
Thanks for the help. Here's the script:
from time import sleep
import sys,os
import subprocess
# Launches the server with specified parameters, waits however
# long is specified in saveInterval, then saves the map.
# Edit the value after "saveInterval =" to desired number of minutes.
# Default is 30
saveInterval = 30
# Start the server. Substitute the launch command with whatever you please.
p = subprocess.Popen('java -Xmx1024M -Xms1024M -jar minecraft_server.jar',
shell=False,
stdin=subprocess.PIPE);
while(True):
sleep(saveInterval*60)
# Comment out these two lines if you want the save to happen silently.
p.stdin.write("say Backing up map...\n")
p.stdin.flush()
# Stop all other saves to prevent corruption.
p.stdin.write("save-off\n")
p.stdin.flush()
sleep(1)
# Perform save
p.stdin.write("save-all\n")
p.stdin.flush()
sleep(10)
# Allow other saves again.
p.stdin.write("save-on\n")
p.stdin.flush()
Replace your sleep() with a call to select((sys.stdin, ), (), (), saveInterval*60) -- that will have the same timeout but listens on stdin for user commands. When select says you have input, read a line from sys.stdin and feed it to your process. When select indicates a timeout, perform the "save" command that you're doing now.
It won't completely solve your problem, but you might find python's cmd module useful. It's a way of easily implementing an extensible command line loop (often called a REPL).
You can run the program using screen, then you can send the input to the specific screen session instead of to the program directly (if you are in Windows just install cygwin).

Categories