6

I decided to try lxdm (was using fluxbox and xfce), and discovered that for many programs the url handler was failing, producing this error message; error message

Quite strange as you can see, it's prepending the user directory to the url. The example here is from telegram, but it happens in discord, as well as when executing from the command line; xdg-open https://www.google.com produces a similar error. xdg-settings get default-web-browser output's firefox.desktop which works as a link in both xfce and lxdm. More information; I ran bash -x on it and...

$ bash -x /usr/bin/xdg-open http://www.google.com
+ check_common_commands http://www.google.com
+ '[' 1 -gt 0 ']'
+ parm=http://www.google.com
+ shift
+ case "$parm" in
+ '[' 0 -gt 0 ']'
+ '[' -z '' ']'
+ unset XDG_UTILS_DEBUG_LEVEL
+ '[' 0 -lt 1 ']'
+ xdg_redirect_output=' > /dev/null 2> /dev/null'
+ '[' xhttp://www.google.com '!=' x ']'
+ url=
+ '[' 1 -gt 0 ']'
+ parm=http://www.google.com
+ shift
+ case "$parm" in
+ '[' -n '' ']'
+ url=http://www.google.com
+ '[' 0 -gt 0 ']'
+ '[' -z http://www.google.com ']'
+ detectDE
+ unset GREP_OPTIONS
+ '[' -n LXDE ']'
+ case "${XDG_CURRENT_DESKTOP}" in
+ DE=lxde
+ '[' xlxde = x ']'
+ '[' xlxde = x ']'
+ '[' xlxde = x ']'
+ '[' xlxde = xgnome ']'
+ '[' -f /run/user/1000/flatpak-info ']'
+ '[' xlxde = x ']'
+ DEBUG 2 'Selected DE lxde'
+ '[' -z '' ']'
+ return 0
+ case "${BROWSER}" in
+ case "$DE" in
+ open_lxde http://www.google.com
+ pcmanfm --help -a is_file_url_or_path http://www.google.com
++ file_url_to_path http://www.google.com
++ local file=http://www.google.com
++ echo http://www.google.com
++ grep -q '^file:///'
++ echo http://www.google.com
+ local file=http://www.google.com
+ echo http://www.google.com
+ grep -q '^/'
++ pwd
+ file=/home/nesmerrill/.local/share/applications/http://www.google.com
+ pcmanfm /home/nesmerrill/.local/share/applications/http://www.google.com
+ '[' 0 -eq 0 ']'
+ exit_success
+ '[' 0 -gt 0 ']'
+ exit 0

The important part seems to be pcmanfm --help -a is_file_url_or_path http://www.google.com but, that command if that's how it was used, doesn't seem to do much of anything?

$ pcmanfm --help -a is_file_url_or_path http://www.google.com
Usage:
  pcmanfm [OPTION…] [FILE1, FILE2,...]  

Help Options:
  -h, --help                   Show help options
  --help-all                   Show all help options
  --help-gtk                   Show GTK+ Options

Application Options:
  -p, --profile=PROFILE        Name of configuration profile
  -d, --daemon-mode            Run PCManFM as a daemon
  --no-desktop                 No function. Just to be compatible with nautilus
  --desktop                    Launch desktop manager
  --desktop-off                Turn off desktop manager if it's running
  --desktop-pref               Open desktop preference dialog
  --one-screen                 Use --desktop option only for one screen
  -w, --set-wallpaper=FILE     Set desktop wallpaper from image FILE
  --wallpaper-mode=MODE        Set mode of desktop wallpaper. MODE=(color|stretch|fit|crop|center|tile|screen)
  --show-pref=N                Open Preferences dialog on the page N
  -n, --new-win                Open new window
  -f, --find-files             Open a Find Files window
  --role=ROLE                  Window role for usage by window manager
  --display=DISPLAY            X display to use
5
  • Had something similar here, In my case it was user error. Your example works fine on my machine though. Judging from the output, your machine thinks it has a file rather than a url.........
    – bu5hman
    Jun 16 '18 at 22:44
  • Had something similar here, In my case it was user error. Your example works fine on my machine though. Judging from the output, your machine thinks it has a file rather than a url.........
    – bu5hman
    Jun 16 '18 at 22:44
  • Yeah that was my judgement too. But the method to test if it's a file or url seems to be passing it off to PCManFM... which is just bizarre. For now, I just deleted that part of the script and it now opens urls... but next time xdg updates? poof.
    – Evil Spork
    Jun 17 '18 at 1:49
  • Point was, did you look at the way the programmes are registered in your DE? xdg-open behaves differently depending what it is told to expect......
    – bu5hman
    Jun 18 '18 at 19:56
  • Yes, I looked into it, and it was calling PCManFM on LXDE, as I said in the post. Which is a very strange call for a url. Deleting that part of the function Open_LXDE() allowed xdg to function on urls. Which is a hack, and doesn't really solve the root problem. Now I can't open file:// with xdg!
    – Evil Spork
    Jun 20 '18 at 10:43
10

@user310685 got it close - but DEFINITELY WRONG. That fix "works" only when xdg-open is NOT given "naked" file paths (i.e. with no leading "file://" URI scheme and double-slash) or file-schemed URI's (i.e. with the leading "file://"). Those two types of argument should have xdg-open defer to pcmanfm, but they won't.

The actual error is not a mistake in the STDERR redirection. Rather, it's that the script writer confused the test "and" operator and the shell's process list "and" connector. The one (erroneously) used is "-a"; the correct one is "&&".

As reference, I've reproduced the original script line, my fix for that line, and the "horror of horrors" suggestion by @user310685:

#ORIG#   if pcmanfm --help >/dev/null 2>&1 -a is_file_url_or_path "$1"; then
#FIXED#  if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then
#HORROR# if pcmanfm --help >/dev/null 2>$1 -a is_file_url_or_path "$1"; then

The intention of the if ..; then is given in the script line just above it:

# pcmanfm only knows how to handle file:// urls and filepaths, it seems.

With this comment in mind, the way to understand the problematic if .. then line is:

  1. Test if pcmanfm is runnable (by having it report it's own help, and discarding any STDOUT or STDERR)
  2. AND, run the script-function is_file_url_or_path() to then see if the "$1" argument is acceptable to pcmanfm (as per the code comment noted above)

If both these conditions hold, then the script flows into a short block that:

  1. Calls the script-function file_url_to_path() to strip off any leading "file://" part (as local var file)
  2. If the result is NOT an absolute path (i.e. doesn't start with "/"), then prepend the CWD to the value of file
  3. Execute pcmanfm "$file"

Why the Original Script Fails:

As noted above, the script is (erroneously) using "-a" as a "process list and operator." What actually happens is that the shell runs the command (after STDOUT and STDERR redirections are "pulled out" of the command, which are allowed to be anywhere in the command word sequence after the first word):

pcmanfm --help -a is_file_url_or_path "$1"

This always succeeds (unless pcmanfm isn't executable on the PATH). All the extra stuff on the command line (-a ..) is ignored by pcmanfm running it's --help mode. Thus, the "process as a file or file-URL" code block is always executed. When given an URL (with a scheme part), the file_url_to_path() script-function only removes a leading "file://", truncates any trailing "#..." fragment, and also URI-decodes the argument (i.e. "%XX" are converted to ASCII). NOTE: Unless the argument starts with "file:///", nothing is done.

For example, the OP's URL "https://www.google.com" is unchanged by file_url_to_path() since it does not begin with "file:///". BUT later code then considers this argument to be a "relative path" since it clearly doesn't start with "/". Thus, it prepends the CWD as described and then pcmanfm is almost certainly NOT going to find that munged value as an extant path to display. Instead, it shows an error pop-up, as in the OP's question.

The Fix:

Simple enough: use the correct syntax for a process chain AND-operator: "&&" as shown in the #FIXED# line, above.

The HORROR of @user310685's Suggestion:

What @user310685 proposes does fix one problem, sort of. What happens is that the shell dutifully does variable expansion and then attempts to execute something like:

pcmanfm --help >/dev/null 2>https://www.google.com -a is_file_url_or_path https://www.google.com

This, is almost certainly going to produce a shell redirection error (unless the CWD has a folder (in the right place) named "https:" - which it could). That redirection error spits a message to STDERR, and then the shell moves on. Since this error occured within an if .. else .. fi block, the shell takes the else .. fi part, which is what @user310685 wants. Thus, the problem is solved...

BUT AT WHAT COST???

There are two problems with this not-quite-right fix:

  1. When actually given a path or a file-schemed URL, the wrong code path is executed (the else .. fi part). This is because the intended process chain is really only a single process that (almost) always generates a shell redirection error which is taken as the if .. ; condition as being "false." This not soooo bad, since that else .. fi block merely defers work to another script-function called open_generic() which is designed to handle paths and file-URL's (but not using pcmanfm to do the work, rather some other complex code-path that I didn't analyze but I presume does a fair job). But WAIT! The HORROR...
  2. Look back up at the pcmanfm --help ... expanded script line that the shell attempts. Note the redirection of STDERR. Consider what happens if this is done with a legitimate path, like "/home/user/precious". OMG The attept to probe if pcmanfm is available and then to test if the argument is a file just OVERWROTE THE FILE!!! Bye-bye precious...
2
  • Thanks for this. Well thought out and with good examples. I never even noticed the -a bit was meant to be an &&
    – Evil Spork
    Aug 31 '19 at 16:34
  • 1
    Apparently, this bug has been fixed - but has not made it's way downstream into the current package release. Until then, it's easiest to just modify xdg-open as mentioned. See bugs.debian.org/cgi-bin/bugreport.cgi?bug=908760#25
    – Stevel
    Sep 2 '19 at 15:43
2

This for Debian 10 (buster), LXDE and xdg-utils 1.1.3-1 too. There is a typo in the xdg-open script and the solution is as follows:

    --- /usr/bin/xdg-open   2018-05-20 00:18:48.000000000 +0200
+++ /home/klaumi/bin/xdg-open   2018-09-13 15:15:51.630704599 +0200
@@ -928,7 +928,7 @@
 {

     # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
-    if pcmanfm --help >/dev/null 2>&1 -a is_file_url_or_path "$1"; then
+    if pcmanfm --help >/dev/null 2>$1 -a is_file_url_or_path "$1"; then
         local file="$(file_url_to_path "$1")"

         # handle relative paths

(Note that & in 2>&1 has to be replaced with $)

2
  • 1
    Please provide reference.
    – user88036
    Sep 13 '18 at 13:39
  • 1
    Please DON'T USE THIS "SOLUTION" - it might actually overwrite your files (not likely, all things considered, but still possible). Anyway, it only gets past the actual defect by accident. See my answer for fuller explanation and a true solution.
    – Stevel
    Aug 30 '19 at 1:14
1

Confirmed for Debian 10 (buster), LXDE, xdg-utils 1.1.3-1. Looks like a bug? One option that doesn't require editing /usr/bin/xdg-open:

  • You can ask xdg-open to use a different desktop environment's handler (ref 1): XDG_CURRENT_DESKTOP=gnome xdg-open https://www.google.com

1
  • I have the same problem in openSUSE with LXDE. Your solution doesn't work, unfortunately.
    – rominf
    Nov 28 '18 at 15:31
0

The Seiji Adachi fix which he calls temporary works for me well https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=906766

1
  • 1
    That fix doesn't do what they think it does. [ pcmanfm -help >/dev/null 2>&1 -a ... ] is simply going to fail every time, because that doesn't fit [ ... ]'s syntax. The correct fix is in the accepted answer.
    – muru
    Dec 12 '19 at 6:52

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.