In Linux, the standard command-line utility used to open a file with its preferred or "proper" application (based on its MIME type) is xdg-open.
Part of the xdg-utils package, this tool is desktop-agnostic, meaning it works whether you are using GNOME, KDE, XFCE, or even a basic window manager, provided the underlying desktop environment tools are installed.
Using xdg-open
The syntax is straightforward. You simply pass the file path or URL as an argument:
xdg-open filename.pdf # Opens in your default PDF viewer
xdg-open image.png # Opens in your default image viewer
xdg-open https://google.com # Opens in your default web browser
How it works
xdg-open looks at the file's extension and content to determine its MIME type. It then consults the desktop's association files (usually found in /usr/share/applications or ~/.local/share/applications/mimeapps.list) to find which application is registered to handle that type.
Alternatives
Depending on your specific environment, you might also see these commands, though xdg-open is the most portable:
gio open: The modern replacement forgvfs-open, used primarily in GNOME/Gtk environments.kde-open: The specific handler for KDE Plasma environments.open: On macOS, this is the equivalent command (on some Linux distros,openis aliased toopenvt, which is different).
Python Implementation
If you are working in Python and prefer PEP 8 standards, you can invoke this functionality using the subprocess module. This is useful if you want your Python script to trigger the system's default viewer for a generated report or image.
import subprocess
import sys
from typing import List
def open_file_with_default_handler(filepath: str) -> None:
"""
Open a file using the system's default application.
Args:
filepath: The path to the file to be opened.
"""
try:
if sys.platform.startswith('linux'):
subprocess.run(['xdg-open', filepath], check=True)
elif sys.platform == 'darwin': # macOS
subprocess.run(['open', filepath], check=True)
elif sys.platform == 'win32': # Windows
subprocess.run(['start', filepath], shell=True, check=True)
except subprocess.CalledProcessError as err:
print(f"Failed to open file: {err}")
if __name__ == "__main__":
# Example usage
open_file_with_default_handler("example_document.pdf")
Unit Test
Following your requirement for unittest and type hints:
import unittest
from unittest.mock import patch
import sys
class TestFileHandler(unittest.TestCase):
"""Tests for the open_file_with_default_handler function."""
@patch('subprocess.run')
def test_open_file_linux(self, mock_run: unittest.mock.MagicMock) -> None:
"""Test that xdg-open is called correctly on Linux platforms."""
# Force platform to linux for the test
with patch('sys.platform', 'linux'):
from file_opener import open_file_with_default_handler
test_path: str = "test.txt"
open_file_with_default_handler(test_path)
mock_run.assert_called_once_with(['xdg-open', test_path],
check=True)
if __name__ == '__main__':
unittest.main()
No comments:
Post a Comment