I know about xdg-mime which can query the mapping from MIME filetype to associated desktop application. But this can return mappings to non-existent applications, e.g.

$ xdg-mime default non-existent.desktop x-scheme-handler/http             
$ xdg-mime query default x-scheme-handler/http                  

How can I programmatically determine whether a given desktop application is valid, i.e. installed? I'm guessing that this would require searching both $XDG_DATA_HOME and the paths in $XDG_DATA_DIRS, but it seems that there should be some kind of utility for querying this application database, rather than having to do it manually.

AFAICS, many of the xdg-* utilities are shell scripts containing a function desktop_file_to_binary which provides something very close to what I want, but I can't see any way of accessing this function directly via those utilities. Of course, I could copy it into my own script, but that obviously sucks, because it's an unofficial solution which violates the privacy of the implementation.

  • Had there been such a tool they would have used it - instead of writing scripts and shell functions... The database is called mimeinfo.cache - it is updated every time update-desktop-database is run in those directories. So what you could do is update the cache files (that would ensure you have no invalid entries) then use grep -q '[=;]your-file\.desktop' on them and check the exit status. Unless you want to run a simple, fast, plain find in those directories which would be faster and would only require read access. This does sound like a XY question to me though... – don_crissti Aug 24 '16 at 10:01

Let me preface this by saying this is what I consider a "good enough" solution because it is simple and should work in a lot of cases, but caution on relying on it 100%.

which $(grep -m 1 Exec $(locate --existing --limit 1 $(xdg-mime query default x-scheme-handler/http)) | cut -f2 -d'=' | cut -f1 -d' ') > /dev/null ; echo $?

If the above outputs 0, then then the application exists.

Breaking it down:

locate --existing --limit 1 $(xdg-mime query default x-scheme-handler/http)

Locates the first file matching the name returned by xdg-mime. The locate command should work for this most of the time as in my experience, most systems' XDG_DATA_DIRS are located in /usr/share /usr/local, which is usually included in the database used by the locate command. However, there are special cases where this may not be true and/or there should be some ordering to which desktop file is read first and used (maybe some user specific file). So technically, this may not be "proper", but it is simple and easier than parsing $XDG_DATA_DIRS and $XDG_DATA_HOME

grep -m 1 Exec $(locate ...) | cut -f2 -d'=' | cut -f1 -d' '

This greps the result from locate (a file path) and tries to cut out the name of the binary or command from the first line in the file with Exec.

which $(grep ...) > /dev/null ; echo $?

Attempts to locate the result from grep, discard standard output and output the exit status (0 on success). This assumes the application is in your PATH.

  • Thanks but as you say this is an unreliable solution, which a) can easily fail if there are more than one matching foo.desktop file on the filesystem (even ones outside the official XDG directories could be used) and b) fails to deal with Exec lines which include parameters such as %u. So in the absence of something better, I'll stick with plagiarising desktop_file_to_binary from xdg-mime for now. Duplicating code is ugly, but at least it's correct. – Adam Spiers Aug 24 '16 at 15:34
  • a) Duplicates aren't an issue. This finds the first foo.desktop, and they should point to the same application. For example, I have two firefox.desktop files, but they both lead to firefox so looking at the first one works. b) This does handle the Exec parameters in the second cut. I just peeked at desktop_file_to_binary and it is not that much different, mainly the ordering of directories it checks to find the first foo.desktop. – Paul Nordin Aug 24 '16 at 18:12
  • There is absolutely no guarantee they'll point to the same application. There's not even a guarantee that any of them are valid desktop files! Sorry - you're right about the cut though; I was testing without that bit. desktop_file_to_binary is fundamentally different in that it only checks valid directories in the right order, rather than the whole filesystem. Those are both crucial differences! – Adam Spiers Aug 24 '16 at 21:01
  • Yes, no guarantee, I only meant most of the time (name clashes aside). I agree, the desktop_file_to_binary idea is more reliable. Anyway, just one last hacky thought: touch test.ext ; xdg-open test.ext >/dev/null 2>&1 && echo 'success' || echo 'failed' ; rm test.ext ... Main problem is the irritating message box or opening of the program ... maybe lsof and kill could help, but it seems like a lot of pain to avoid violating the implementation's privacy. – Paul Nordin Aug 25 '16 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.