Skip to content

Instantly share code, notes, and snippets.

@ytturi
Last active November 19, 2022 06:19
Show Gist options
  • Save ytturi/0c23ad5ab89154d24c340c2b1cc3432b to your computer and use it in GitHub Desktop.
Save ytturi/0c23ad5ab89154d24c340c2b1cc3432b to your computer and use it in GitHub Desktop.
Python: Use a subprocess to open a file with it's default program on multi-platform OS
# -*- coding: utf-8 -*-
# ------------------------------------------------------
# Author: Ytturi
# Author's e-mail: ytturi@protonmail.com
# Original Gist: https://gist.github.com/ytturi/0c23ad5ab89154d24c340c2b1cc3432b
# Version: 0.1
# License: MIT
# ------------------------------------------------------
# This script allows the user to run the default program
# to open a file for it's given type or extension.
#
# It contains the `subprocess_open` method that calls
# for the program in a subprocess using subprocess' Popen.
#
# But also the `get_open_command` that returns the
# script to run in a shell so you can call it as you want.
#
# If you want to test it, you can use this same script to
# open the file.
# Note that "click" is required in order to test it.
# ------------------------------------------------------
from subprocess import Popen, PIPE
from subprocess import check_output
from platform import system
OSNAME = system().lower()
def get_open_command(filepath):
"""
Get the console-like command to open the file
for the current platform:
- Windows: "start {{ filepath }}"
- OS X: "open {{ filepath }}"
- Linux based (wdg): "wdg-open {{ filepath }}"
:param filepath: Path to the file to be opened
:type filepath: string
:return: Command to run from a shell
:rtype: string
"""
if 'windows' in OSNAME:
opener = 'start'
elif 'osx' in OSNAME or 'darwin' in OSNAME:
opener = 'open'
else:
opener = 'xdg-open'
return '{opener} {filepath}'.format(opener=opener, filepath=filepath)
def subprocess_opener(filepath):
"""
Method to open the file with the default program in a subprocess.
As being called in a subprocess, it will not block the current one.
This method runs the command on a subprocess using the default system shell.
Check the docs of subprocess module for more info:
https://docs.python.org/2/library/subprocess.html#subprocess.Popen
The subprocess will run in background so you won't be able to bring back
the result code, but the current log can be obtained via the Popen's PIPE:
Usage:
```
# Run as subprocess
subproc = subprocess_opener(filepath)
# Get the stdout for the subprocess
print(subproc.stdout)
# Get the stderr for the subprocess
print(subproc.stderr)
```
:type filepath: string
:param filepath: Path to the file to open
:rtype: subprocess
:return: The pointer the subprocess returned by the Popen call
"""
subproc = Popen(
get_open_command(filepath),
stdout=PIPE, stderr=PIPE, shell=True
)
subproc.wait()
return subproc
# Code to run it as a script
if __name__ == '__main__' :
import click
@click.command()
@click.argument('filepath')
@click.option(
'-v', '--verbose', type=bool, is_flag=True, default=False,
help='Show verbose messages')
def command_opener(filepath, verbose):
from os.path import isfile
if not isfile(filepath):
print('Filepath does not get to a file!')
exit(-1)
if verbose:
print('Opening: "{}" with: "{}"'.format(
filepath, get_open_command(filepath=filepath)))
subproc = subprocess_opener(filepath)
if verbose:
print('File opened in a child process')
command_opener()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment