You are not logged in.
Some file managers (e.g. Rox) can launch an application when you click on its .desktop file in /usr/share/applications. Many don't. Is there a command line utility that can parse .desktop files and launch the correct application, which I can associate with .desktop files in file managers like mc or xfe?
Offline
The ones that don't work, do they have the following in them
Exec=/path/to/command
There's no such thing as a stupid question, but there sure are a lot of inquisitive idiots !
Offline
It's not the .desktop files that don't work, it's the file managers. For instance Xfe will just open .desktop files as text, whereas Rox will open the application they belong to by default. I'd like to have that latter behavior in Xfe, and was wondering if there was any command line utility for executing an application based on a .desktop file.
Offline
You could do "xdg-open whatever.desktop".
Offline
You could do "xdg-open whatever.desktop".
That opens the desktop file based on file-type associations, which is what the file browsers are already doing.
@Gullible Jones
Here's a script that will open the application of the Exec key in the desktop file. Pass it the path to the desktop file as the first argument. Additional arguments will be passed through to the application.
The code has been ripped from mimeo and tweaked a bit. I've only done some quick testing but the Exec command parser should be fully compliant with the Desktop specification, so it should work with everything.
If you find any bugs, let me know, as they may affect mimeo as well.
#!/usr/bin/env python2
# Author: Xyne
import os, os.path, re, subprocess, sys
from pipes import quote
def launch(args):
subprocess.Popen(args, shell=True, close_fds=True)
def parseDesktop(fpath):
desktop = {}
if os.path.exists(fpath):
try:
f = open(fpath)
except IOError:
print "error: unable to open", fpath
else:
for line in f.readlines():
m = re.search(r'^\s*(.+?)\s*=\s*(.+?)\s*$', line)
if m:
desktop[m.group(1)] = m.group(2)
return desktop
def which(cmd):
def isExecutable(fpath):
return os.path.exists(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(cmd)
if fpath:
cmd = os.path.abspath(cmd)
if isExecutable(cmd):
return cmd
else:
for p in os.environ["PATH"].split(os.pathsep):
fpath = os.path.join(p, fname)
if isExecutable(fpath):
return fpath
return None
# http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
def parse_exec_key(key, user_args):
#reserved = " \t\n\"\'\\><~|&;$*?#()`"
quoted = False
escaped = False
percent = False
# Track field codes which may only occur once and alone.
seen = False
# Track where to insert replacements for %f and %u.
insertion_point = None
# Track skipped variables to prevent empty arguments, e.g. '%x' -> ''.
skipped = False
args = []
a = ""
for c in key:
if escaped:
escaped = False
elif percent:
percent = False
if c == '%':
pass
else:
# skip some fields that appear more than once
if 'fFuU'.find(c) > -1:
if seen:
skipped = True
continue
else:
seen = True
if c == 'f' or c == 'u':
insertion_point = (len(args), len(a))
elif c == 'F' or c == 'U':
a += '%' + c
# TODO: implement remaining
elif c == 'i' or c == 'c' or c == 'k':
skipped = True
continue
elif quoted:
if c == '\\':
escaped = True
continue
elif c == '%':
percent = True
continue
elif c == '"':
quoted = False
continue
elif c == '"':
quoted = True
continue
elif c == '%':
percent = True
continue
elif c == ' ':
if a or not skipped:
args.append(a)
a = ""
skipped = False
continue
a += c
if a or not skipped:
args.append(a)
cmd = args[0]
cpath = which(cmd)
if not cpath:
die("invalid executable (%s)" % cmd)
else:
args[0] = cpath
if not user_args:
return [cpath]
if insertion_point:
i, j = insertion_point
a = args[i]
cmds = []
for user_arg in user_args:
b = a[:j] + user_arg + a[j:]
args[i] = b
cmds.append(quote_command(args))
return cmds
else:
cmd = []
complete = False
for a in args:
if a == "%F" or a == "%U":
cmd.extend(user_args)
complete = True
else:
cmd.append(a)
if not complete:
cmd.extend(user_args)
return [quote_command(cmd)]
def quote_command(args):
return ' '.join( map(quote, args) )
def die(msg):
sys.stderr.write("error: %s\n" % msg)
sys.exit(1)
def main():
try:
fpath = sys.argv[1]
except IndexError:
die("no desktop file specified")
args = sys.argv[2:]
desktop = parseDesktop(fpath)
if not desktop:
die("%s does not exist" % fpath)
elif desktop.has_key('Exec'):
execCmd = desktop['Exec']
for cmd in parse_exec_key(execCmd, args):
launch(cmd)
else:
die("%s does not contain an \"Exec\" field" % fpath)
if __name__ == "__main__":
main()
Last edited by Xyne (2011-01-26 18:36:06)
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
Err... Thank you. Thank you very much.
Offline