Im trying to call a script to run some commands in remote dev server with this path.
Sample code for dev server
def funcA():
if os.path.exists("/opt/dev/bin"):
process = subprocess.run(["ls", "****" , "*****"],stdout=subprocess.PIPE)
else:
print("the path doesnt exist")
sys.exit(2)
When i run it it works fine. I want to modify the script in such a way that i can check paths in different environment
I tried this
def funcA():
path=sys.argv[1]
if os.path.exists(path):
process = subprocess.run(["ls", "****" , "*****"],stdout=subprocess.PIPE)
else:
print("the path doesnt exist")
sys.exit(2)
i add the path as argument it works fine.
sample.py /opt/prod/bin
Is there a better way to do this ? instead of entering the whole path as argument such as asking the user which environment(prod,test etc) and updating the path accordingly ?
Related
Hello guys I have opened 3 python scripts that they are running at the same time. I want to terminate(Kill) one of them with other python file. It means if we run many python scripts at the same time how to terminate or kill one of them or two of them? Is it possible with os or subprocess modules? I try to use them but they kill all python scripts with killing python.exe
FirstSc.py
UserName = input("Enter your username = ")
if UserName == "Alex":
#Terminate or Kill the PythonFile in this address C:\MyScripts\FileTests\SecondSc.py
SecondSc.py
while True:
print("Second app is running ...")
ThirdSc.py
while True:
print("Third app is running ...")
Thanks guys I get good answers. Now if we have a Batch file like SecBatch.bat instead of SecondSc.py how to do this. It means we have these and run FirstSc.py and SecBatch.bat at the same time:
FirstSc.py in this directory D:\MyFiles\FirstSc.py
UserName = input("Enter your username = ")
if UserName == "Alex":
#1)How to print SecBatch.bat syntax it means print:
#CALL C:\MyProject\Scripts\activate.bat
#python C:\pyFiles\ThirdSc.py
#2)Terminate or kill SecBatch.bat
#3)Terminate or kill ThirdSc.py
SecBatch.bat in this directory C:\MyWinFiles\SecBatch.bat that it run a Python VirtualEnvironment then run a python script in this directory C:\pyFiles\ThirdSc.py
CALL C:\MyProject\Scripts\activate.bat
python C:\pyFiles\ThirdSc.py
ThirdSc.py in this directory C:\pyFiles\ThirdSc.py
from time import sleep
while True:
print("Third app is running ...")
sleep(2)
I would store the PID of each script in a standard location. Assuming you are running on Linux I would put them in /var/run/. Then you can use os.kill(pid, 9) to do what you want. Some example helper funcs would be:
import os
import sys
def store_pid():
pid = os.getpid()
# Get the name of the script
# Example: /home/me/test.py => test
script_name = os.path.basename(sys.argv[0]).replace(".py", "")
# write to /var/run/test.pid
with open(f"/var/run/{script_name}.pid", "w"):
f.write(pid)
def kill_by_script_name(name):
# Check the pid file is there
pid_file = f"/var/log/{name}.pid"
if not os.path.exists(pid_file):
print("Warning: cannot find PID file")
return
with open(pid_file) as f:
# The following might throw ValueError if pid file has characters
pid = int(f.read().strip())
os.kill(pid, 9)
Later in FirstSc:
if UserName == "Alex":
kill_by_script_name("SecondSc")
kill_by_script_name("ThirdSc")
NOTE: The code is not tested :) but should point to you to the correct direction (at least for one common way to solve this problem)
You may be able to terminate a Python process by the name of the script file using system commands such as taskkill (or pkill on Linux systems). However, a better way to accomplish this would be (if possible) to have FirstSc.py or whatever script that's doing the killing launch the other scripts using subprocess.Popen(). Then you can call terminate() on it to end the process:
import subprocess
# Launch the two scripts
# You may have to change the Python executable name
second_script = subprocess.Popen(["python", "SecondSc.py"])
third_script = subprocess.Popen(["python", "ThirdSc.py"])
UserName = input("Enter your username = ")
if UserName == "Alex":
second_script.terminate()
I want to redirect o/p of shell commands to file using variable "path" but it is not working
import os, socket, shutil, subprocess
host = os.popen("hostname -s").read().strip()
path = "/root/" + host
if os.path.exists(path):
print(path, "Already exists")
else:
os.mkdir("Directory", path , "Created")
os.system("uname -a" > path/'uname') # I want to redirect o/p of shell commands to file using varibale "path" but it is not working
os.system("df -hP"> path/'df')
I think the problem is the bare > and / symbols in the os.system command...
Here is a python2.7 example with os.system that does what you want
import os
path="./test_dir"
command_str="uname -a > {}/uname".format(path)
os.system(command_str)
Here's a very minimal example using subprocess.run. Also, search StackOverflow for "python shell redirect", and you'll get this result right away:
Calling an external command in Python
import subprocess
def run(filename, command):
with open(filename, 'wb') as stdout_file:
process = subprocess.run(command, stdout=subprocess.PIPE, shell=True)
stdout_file.write(process.stdout)
return process.returncode
run('test_out.txt', 'ls')
Duplicate edit: no, i did that but it doesnt want to launch firefox.
I am making a cortana/siri assistant thing, and I want it to lets say open a web browser when I say something. So I have done the if part, but I just need it to launch firefox.exe I have tried different things and I get an error . Here is the code. Please help! It works with opening notepad but not firefox..
#subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe']) opens the app and continues the script
#subprocess.call(['C:\Program Files\Mozilla Firefox\firefox.exe']) this opens it but doesnt continue the script
import os
import subprocess
print "Hello, I am Danbot.. If you are new ask for help!" #intro
prompt = ">" #sets the bit that indicates to input to >
input = raw_input (prompt) #sets whatever you say to the input so bot can proces
raw_input (prompt) #makes an input
if input == "help": #if the input is that
print "*****************************************************************" #says that
print "I am only being created.. more feautrues coming soon!" #says that
print "*****************************************************************" #says that
print "What is your name talks about names" #says that
print "Open (name of program) opens an application" #says that
print "sometimes a command is ignored.. restart me then!"
print "Also, once you type in a command, press enter a couple of times.."
print "*****************************************************************" #says that
raw_input (prompt) #makes an input
if input == "open notepad": #if the input is that
print "opening notepad!!" #says that
print os.system('notepad.exe') #starts notepad
if input == "open the internet": #if the input is that
print "opening firefox!!" #says that
subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe'])
The short answer is that os.system doesn't know where to find firefox.exe.
A possible solution would be to use the full path. And it is recommended to use the subprocess module:
import subprocess
subprocess.call(['C:\Program Files\Mozilla Firefox\\firefox.exe'])
Mind the \\ before the firefox.exe! If you'd use \f, Python would interpret this as a formfeed:
>>> print('C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox
irefox.exe
And of course that path doesn't exist. :-)
So either escape the backslash or use a raw string:
>>> print('C:\Program Files\Mozilla Firefox\\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe
>>> print(r'C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe
Note that using os.system or subprocess.call will stop the current application until the program that is started finishes. So you might want to use subprocess.Popen instead. That will launch the external program and then continue the script.
subprocess.Popen(['C:\Program Files\Mozilla Firefox\\firefox.exe', '-new-tab'])
This will open firefox (or create a new tab in a running instance).
A more complete example is my open utility I publish via github. This uses regular expressions to match file extensions to programs to open those files with. Then it uses subprocess.Popen to open those files in an appropriate program. For reference I'm adding the complete code for the current version below.
Note that this program was written with UNIX-like operating systems in mind. On ms-windows you could probably get an application for a filetype from the registry.
"""Opens the file(s) given on the command line in the appropriate program.
Some of the programs are X11 programs."""
from os.path import isdir, isfile
from re import search, IGNORECASE
from subprocess import Popen, check_output, CalledProcessError
from sys import argv
import argparse
import logging
__version__ = '1.3.0'
# You should adjust the programs called to suit your preferences.
filetypes = {
'\.(pdf|epub)$': ['mupdf'],
'\.html$': ['chrome', '--incognito'],
'\.xcf$': ['gimp'],
'\.e?ps$': ['gv'],
'\.(jpe?g|png|gif|tiff?|p[abgp]m|svg)$': ['gpicview'],
'\.(pax|cpio|zip|jar|ar|xar|rpm|7z)$': ['tar', 'tf'],
'\.(tar\.|t)(z|gz|bz2?|xz)$': ['tar', 'tf'],
'\.(mp4|mkv|avi|flv|mpg|movi?|m4v|webm)$': ['mpv']
}
othertypes = {'dir': ['rox'], 'txt': ['gvim', '--nofork']}
def main(argv):
"""Entry point for this script.
Arguments:
argv: command line arguments; list of strings.
"""
if argv[0].endswith(('open', 'open.py')):
del argv[0]
opts = argparse.ArgumentParser(prog='open', description=__doc__)
opts.add_argument('-v', '--version', action='version',
version=__version__)
opts.add_argument('-a', '--application', help='application to use')
opts.add_argument('--log', default='warning',
choices=['debug', 'info', 'warning', 'error'],
help="logging level (defaults to 'warning')")
opts.add_argument("files", metavar='file', nargs='*',
help="one or more files to process")
args = opts.parse_args(argv)
logging.basicConfig(level=getattr(logging, args.log.upper(), None),
format='%(levelname)s: %(message)s')
logging.info('command line arguments = {}'.format(argv))
logging.info('parsed arguments = {}'.format(args))
fail = "opening '{}' failed: {}"
for nm in args.files:
logging.info("Trying '{}'".format(nm))
if not args.application:
if isdir(nm):
cmds = othertypes['dir'] + [nm]
elif isfile(nm):
cmds = matchfile(filetypes, othertypes, nm)
else:
cmds = None
else:
cmds = [args.application, nm]
if not cmds:
logging.warning("do not know how to open '{}'".format(nm))
continue
try:
Popen(cmds)
except OSError as e:
logging.error(fail.format(nm, e))
else: # No files named
if args.application:
try:
Popen([args.application])
except OSError as e:
logging.error(fail.format(args.application, e))
def matchfile(fdict, odict, fname):
"""For the given filename, returns the matching program. It uses the `file`
utility commonly available on UNIX.
Arguments:
fdict: Handlers for files. A dictionary of regex:(commands)
representing the file type and the action that is to be taken for
opening one.
odict: Handlers for other types. A dictionary of str:(arguments).
fname: A string containing the name of the file to be opened.
Returns: A list of commands for subprocess.Popen.
"""
for k, v in fdict.items():
if search(k, fname, IGNORECASE) is not None:
return v + [fname]
try:
if b'text' in check_output(['file', fname]):
return odict['txt'] + [fname]
except CalledProcessError:
logging.warning("the command 'file {}' failed.".format(fname))
return None
if __name__ == '__main__':
main(argv)
If you want to open Google or something on the web just import webbrowser and open the URL. I will give you a quick example.
import webbrowser
webbrowser.open("www.google.com")
You can open any program like this:
import subprocess
# This will pause the script until fortnite is closed
subprocess.call(['C:\Program Files\Fortnite\fortnite.exe'])
# But this will run fortnite and continue the script
subprocess.Popen(['C:\Program Files\Fortnite\fortnite.exe', '-new-tab'])
But here's How to find the .exe file of any program (Windows only)
I only know how to find the .exe file in windows
First, click the windows icon then write task manager, open it, then find Fortnite if there's an arrow on it's left click it, if there's another one click it.
Make sure that you press the More Details button at the bottom.
Then scroll to the side until you find Command line written on the top row, here there will be the path of the .exe file of every running task
There might be -(SOME_LETTER) but these are some options for choosing what the exe file will do when it's ran. These are different for every exe file
(Little tips)
You can press Ctrl+Shift+Esc to open the task manager.
Go in the task manager then press Options (at the top) then press Always on top, which will make the app appear on top of every thing which is pretty useful when an app crashes and you need to close it using the task manager
Thanks.
I am writing a script to extract something from a specified path. I am returning those values into a variable. How can i check whether the shell command has returned something or nothing.
My Code:
def any_HE():
global config, logger, status, file_size
config = ConfigParser.RawConfigParser()
config.read('config2.cfg')
for section in sorted(config.sections(), key=str.lower):
components = dict() #start with empty dictionary for each section
#Retrieving the username and password from config for each section
if not config.has_option(section, 'server.user_name'):
continue
env.user = config.get(section, 'server.user_name')
env.password = config.get(section, 'server.password')
host = config.get(section, 'server.ip')
print "Trying to connect to {} server.....".format(section)
with settings(hide('warnings', 'running', 'stdout', 'stderr'),warn_only=True, host_string=host):
try:
files = run('ls -ltr /opt/nds')
if files!=0:
print '{}--Something'.format(section)
else:
print '{} --Nothing'.format(section)
except Exception as e:
print e
I tried checking 1 or 0 and True or false but nothing seems to be working. In some servers, the path '/opt/nds/' does not exist. So in that case, nothing will be there on files. I wanted to differentiate between something returned to files and nothing returned to files.
First, you're hiding stdout.
If you get rid of that you'll get a string with the outcome of the command on the remote host. You can then split it by os.linesep (assuming same platform), but you should also take care of other things like SSH banners and colours from the retrieved outcome.
As perror commented already, the python subprocess module offers the right tools.
https://docs.python.org/2/library/subprocess.html
For your specific problem you can use the check_output function.
The documentation gives the following example:
import subprocess
subprocess.check_output(["echo", "Hello World!"])
gives "Hello World"
plumbum is a great library for running shell commands from a python script. E.g.:
from plumbum.local import ls
from plumbum import ProcessExecutionError
cmd = ls['-ltr']['/opt/nds'] # construct the command
try:
files = cmd().splitlines() # run the command
if ...:
print ...:
except ProcessExecutionError:
# command exited with a non-zero status code
...
On top of this basic usage (and unlike the subprocess module), it also supports things like output redirection and command pipelining, and more, with easy, intuitive syntax (by overloading python operators, such as '|' for piping).
In order to get more control of the process you run, you need to use the subprocess module.
Here is an example of code:
import subprocess
task = subprocess.Popen(['ls', '-ltr', '/opt/nds'], stdout=subprocess.PIPE)
print task.communicate()
I have a small git_cloner script that clones my companies projects correctly. In all my scripts, I use a func that hasn't given me problems yet:
def call_sp(
command, **arg_list):
p = subprocess.Popen(command, shell=True, **arg_list)
p.communicate()
At the end of this individual script, I use:
call_sp('cd {}'.format(branch_path))
This line does not change the terminal I ran my script in to the directory branch_path, in fact, even worse, it annoyingly asks me for my password! When removing the cd yadayada line above, my script no longer demands a password before completing. I wonder:
How are these python scripts actually running? Since the cd command had no permanent effect. I assume the script splits its own private subprocess separate from what the terminal is doing, then kills itself when the script finishes?
Based on how #1 works, how do I force my scripts to change the terminal directory permanently to save me time,
Why would merely running a change directory ask me for my password?
The full script is below, thank you,
Cody
#!/usr/bin/env python
import subprocess
import sys
import time
from os.path import expanduser
home_path = expanduser('~')
project_path = home_path + '/projects'
d = {'cwd': ''}
#calling from script:
# ./git_cloner.py projectname branchname
# to make a new branch say ./git_cloner.py project branchname
#interactive:
# just run ./git_cloner.py
if len(sys.argv) == 3:
project = sys.argv[1]
branch = sys.argv[2]
if len(sys.argv) < 3:
while True:
project = raw_input('Enter a project name (i.e., mainworkproject):\n')
if not project:
continue
break
while True:
branch = raw_input('Enter a branch name (i.e., dev):\n')
if not branch:
continue
break
def call_sp(command, **arg_list):
p = subprocess.Popen(command, shell=True, **arg_list)
p.communicate()
print "making new branch \"%s\" in project \"%s\"" % (branch, project)
this_project_path = '%s/%s' % (project_path, project)
branch_path = '%s/%s' % (this_project_path, branch)
d['cwd'] = project_path
call_sp('mkdir %s' % branch, **d)
d['cwd'] = branch_path
git_string = 'git clone ssh://git#git/home/git/repos/{}.git {}'.format(project, d['cwd'])
#see what you're doing to maybe need to cancel
print '\n'
print "{}\n\n".format(git_string)
call_sp(git_string)
time.sleep(30)
call_sp('git checkout dev', **d)
time.sleep(2)
call_sp('git checkout -b {}'.format(branch), **d)
time.sleep(5)
#...then I make some symlinks, which work
call_sp('cp {}/dev/settings.py {}/settings.py'.format(project_path, branch_path))
print 'dont forget "git push -u origin {}"'.format(branch)
call_sp('cd {}'.format(branch_path))
You cannot use Popen to change the current directory of the running script. Popen will create a new process with its own environment. If you do a cd within that, it will change directory for that running process, which will then immediately exit.
If you want to change the directory for the script you could use os.chdir(path), then all subsequent commands in the script will be run from that new path.
Child processes cannot alter the environment of their parents though, so you can't have a process you create change the environment of the caller.