I’d like to open a few apps using a very simple python script:
from subprocess import call
call("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
call("/Applications/MongoDB Compass.app/Contents/MacOS/MongoDB Compass")
The problem is that opening them this way seems to open a terminal window along with the app itself - for chrome, it outputs this in the terminal for example:
Last login: Sun Oct 23 00:20:38 on ttys000
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome ; exit;
nick#Nicks-MBP ~ % /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome ; exit;
objc[3817]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffb45565ec8) and /Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/106.0.5249.119/Libraries/libGLESv2.dylib (0x116ba9668). One of the two will be used. Which one is undefined.
So it hijacks the terminal and does not proceed to this next line:
call("/Applications/MongoDB Compass.app/Contents/MacOS/MongoDB Compass")
If I try to call these:
call(("/Applications/Google Chrome.app"))
call(("/Applications/MongoDB Compass.app"))
I get this error, with other posts stating that it may be a dir and not an app:
OSError: [Errno 13] Permission denied
How can this be fixed? Note that I do not want to do this despite it working:
os.system("open /Applications/" + app + ".app")
Because I need to be able to wait for the apps to finish opening before running another command, hence the use of Subprocess.call. Thank you.
UPDATE:
I now have this:
print("start")
call(
[("/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome")],
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT,
)
print("end")
But the print("end") line only executes when I exit out of chrome. How can I get it to wait for Chrome to load and then print 'end' after? Also it requires Shell=True for some reason, otherwise it complains with:
FileNotFoundError: [Errno 2] No such file or directory: '/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome
Updated Answer
This also appears to work and doesn't involve the shell:
import subprocess as sp
print("start")
sp.run(["open", "-a", "Google Chrome"])
print("end")
Original Answer
This appears to do what you want, though I have no explanation as to why:
import subprocess as sp
print("start")
sp.Popen(
["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],
stdin =sp.DEVNULL,
stdout=sp.DEVNULL,
stderr=sp.DEVNULL)
print("end")
Related
I'm trying to write a python script that can launch DaVinci Resolve in headless mode, then send it some commands via its API, then close it.
What I'm looking for would look something like
Open resolve.exe with argument --nogui
Do stuff with the API here
Terminate this instance of Resolve
I've managed to launch an instance of Resolve in headless. But it always ends up being a subprocess of something else. While it's running as a subprocess, I can't get the API to communicate with it.
Here's the code of tried
import subprocess
args = ["C:\Program Files\Blackmagic Design\DaVinci Resolve\Resolve.exe", '--nogui']
resolve_headles = subprocess.Popen(args)
from python_get_resolve import GetResolve
resolve = GetResolve()
This should return an object of Resolve, but it always fails.
I believe this is because its running as a subprocess of my IDE
I've also tried this
from subprocess import call
dir = "C:\Program Files\Blackmagic Design\DaVinci Resolve"
cmdline = "Resolve.exe --nogui"
rc = call("start cmd /K " + cmdline, cwd=dir, shell=True)
This just has the same problem of Resolve running as a subprocess of Windows Command Processor.
I want to programmatically initialize a Firefox profile so that all files that are normally created on first run of Firefox are created.
I have tried using firefox -CreateProfile but it only creates the folder and a times.json file. I need the full profile. What I probably need to do is start and close Firefox using Python, but I cannot get Firefox to close.
I am using subprocess.Popen so I can retrieve the pid to later close Firefox with proc.terminate(), but it is not working. The pid's process is no longer found. Perhaps it has something to do with Firefox multiprocess?
import os
import subprocess
import time
profile_name = 'new_profile'
profile_path = f"C:\\Users\\user\\profiles\\{profile_name}"
os.system(f'firefox -CreateProfile "{profile_name} {profile_path}" -no-remote')
proc = subprocess.Popen(['firefox', '-profile', profile_path, '-no-remote'])
print(f"Pid: proc.pid")
time.sleep(3)
proc.terminate() # Not working
time.sleep(1)
os.system(f"taskkill /F /pid {proc.pid}") # Process not found
Running the script and confirming with taskkill the process on the original pid is no longer found:
Pid: 16472
ERROR: The process "16472" not found.
How can I close Firefox using this approach?
this is my first post to stackoverflow, so please bear with me :)
I'm trying to read the output of iwconfig from a python script to determine whether there is a wifi connection. When I run script (via a bash script that first sets the directory) using crontab #reboot (user, not root), subprocess.check_output(['iwconfig']) always throws an [Errno 2]. This is even true when I catch the error using try/except and loop the code, so it is still running when the Wifi is certainly connected (as I can check with running iwconfig manually). When I run the python script from the command line via the same bash script, it works fine. What am I overlooking?
#!/usr/bin/python3
import subprocess
import time
import logging
logging.basicConfig(filename='wifi_check.log', filemode='w', format='%(name)s - %(levelname)s
- %(message)s', level=logging.DEBUG)
logging.info("Checking for Wifi")
for i in range(20):
try:
iwconfig_output = subprocess.check_output(['iwconfig']).decode('utf-8')
except Exception as err:
logging.error(str(i) + str(err))
else:
logging.debug(str(i) + iwconfig_output)
if "ESSID" in iwconfig_output:
logging.info(str(i) + "Wifi active")
time.sleep(10)
Errno 2 can indicate that the file is not found.
Perhaps iwconfig is not in PATH for the user who executes the script. Try using /sbin/iwconfig (the full path) of the executable to rule this out.
I'm working on a program that requires me to keep track of the PIDs of specific Chrome/browser instances. This is the code I wrote for this:
def launch_procs():
low1 = Popen(['google-chrome-stable', 'http://www.google.com'])
med1 = Popen(['google-chrome-stable', 'http://www.netflix.com'])
high1 = Popen(['google-chrome-stable', 'http://www.facebook.com'])
return [low1.pid, med1.pid, high1.pid]
However, when I attempt to reference the PIDs later on in the program it seems that the PIDs have expired. Here is the error I get:
7894
strace: attach: ptrace(PTRACE_ATTACH, ...): No such process
7896
strace: attach: ptrace(PTRACE_ATTACH, ...): No such process
7901
strace: attach: ptrace(PTRACE_ATTACH, ...): No such process
Is the issue that Chrome doesn't assign permanent PIDs to its tabs/processes (i.e. it forks once a Chrome process launches and ditches the parent process)?
Note: This implementation is browser/implementation agnostic, I just need a way to obtain stable access to the PIDs of these launched processes. If anyone has suggestions on doing this they would be very much appreciated.
Thanks!
Chrome does not run as root under normal operating conditions. You can find several discussions for this here and here
There are several arguments that will allow you to circumvent this. By passing --user-data-dir and --no-sandbox you will be able to run chrome as root.
import os
from subprocess import Popen
line_count = 10
outfile = 'foo.txt'
cmd = 'sudo timeout 10 strace -p {} -o temp.out | cat temp.out | tail -{} > {}'
tab_sites = ['www.google.com', 'www.yahoo.com', 'www.msn.com']
for site in tab_sites:
chrome_proc = Popen(['google-chrome-stable', site, '--user-data-dir', '--no-sandbox'])
print(chrome_proc.pid)
os.system(cmd.format(chrome_proc.pid, line_count, outfile))
Alternatively you can use runuser with your command:
import os
import sys
from subprocess import Popen
line_count = 10
outfile = 'foo.txt'
cmd = 'sudo timeout 10 strace -p {} -o temp.out | cat temp.out | tail -{} > {}'
tab_sites = ['www.google.com', 'www.yahoo.com', 'www.msn.com']
for site in tab_sites:
chrome_proc = Popen(['runuser', '-u', sys.argv[1], 'google-chrome-stable', site])
print(chrome_proc.pid)
os.system(cmd.format(chrome_proc.pid, line_count, outfile))
Just pass in the username you want to run this under, sudo python trace_chrome.py your_user_name
I understand you aren't able to show your exact code which does make things tougher to be able to assist.
To see the Process ID's of your Chrome tabs you can open the Task Manager by pressing Shift Esc. I did some testing, and as you suspect, the PID is different than reported by Popen.
One way to get an accessable PID with Chrome is to use the option --temp-profile to create a new session for each site instead of using an existing one.
I am playing around with web scraping and Tor.
I managed to make it work with both requests and Selenium + PhantomJS. However, I need that the Tor browser is opened for the script to work.
This is why I am trying now to automatise the complete process; that is: open Tor browser automatically, run some script and at the end close the browser automatically. But I am struggling with it.
#open Tor browser
os.system('open /Applications/TorBrowser.app')
#code to scrape
#close Tor browser
???
Open
To open the browser, some other options I found out there are not working.
import subprocess
subprocess.Popen('/Applications/TorBrowser.app') #permission denied
or
os.system('start /Applications/TorBrowser.app') #sh: start: command not found
However, the following line worked:
os.system('open /Applications/TorBrowser.app')
Close
The main problem is to close the browser afterwards, as none of the commands found in other posts worked.
Those include:
os.system("taskkill /im /Applications/TorBrowser.app /f") #sh: taskkill: command not found
or
os.system("kill /Applications/TorBrowser.app") #sh: line 0: kill: /Applications/TorBrowser.app: arguments must be process or job IDs
or
os.close('/Applications/TorBrowser.app') #TypeError: an integer is required (got type str)
Any suggestions of how to close it?
And is there a better way to open it?
Edit: I'm on Mac with Python 3.
This worked for me:
from selenium import webdriver
import os
import subprocess
#start Tor
sproc=subprocess.Popen('"C:\\Users\\My name\\Desktop\\Tor Browser\\Browser\\firefox.exe"' )
#start PhantomJS
service_args = [ '--proxy=localhost:9150', '--proxy-type=socks5', ]
driver = webdriver.PhantomJS(service_args=service_args)
#get page
driver.get("https://stackoverflow.com/questions/40161921/how-to-open-and-close-tor-browser-automatically-with-python")
print(driver.page_source)
driver.close()
#kill process
sproc.kill()
I think you should add some time pauses between commands:
import time
time.sleep(20)# wait 20 seconds
Another way to open Tor:
os.system('"C:\\Users\\My Name\\Desktop\\Tor Browser\\Browser\\firefox.exe"' )
But this time your command will wait until the called process stops himself (may be user will close it). According to your question it is not what you want. To control executing process let it runs and use special variable to kill it whenever you want.
Also pay attention to string path: double quotes inside single quotes. There are other ways to pass strings with spaces to system commands, for example: running an outside program (executable) in python?.
Try this in jupyter:
import webbrowser
urL='https://YOUR WEBSITE ADDRESS HERE'
mozilla_path="C:\\Users\\T14s\\Desktop\\Tor Browser\\Browser\\firefox.exe"
webbrowser.register('firefox', None,webbrowser.BackgroundBrowser(mozilla_path))
webbrowser.get('firefox').open_new_tab(urL)
import os
import time
time.sleep(10)
os.system("taskkill /im firefox.exe /f")
TOR is based on firefox - hence firefox comes up a lot.