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;

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
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
@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:
- Test if
pcmanfmis runnable (by having it report it’s own help, and discarding any STDOUT or STDERR) - AND, run the script-function
is_file_url_or_path()to then see if the"$1"argument is acceptable topcmanfm(as per the code comment noted above)
If both these conditions hold, then the script flows into a short block that:
- Calls the script-function
file_url_to_path()to strip off any leading “file://” part (as local varfile) - If the result is NOT an absolute path (i.e. doesn’t start with “/”), then prepend the CWD to the value of
file - 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:
- When actually given a path or a file-schemed URL, the wrong code path is executed (the
else .. fipart). 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 theif .. ;condition as being “false.” This not soooo bad, since thatelse .. fiblock merely defers work to another script-function calledopen_generic()which is designed to handle paths and file-URL’s (but not usingpcmanfmto 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… - 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 ifpcmanfmis available and then to test if the argument is a file just OVERWROTE THE FILE!!! Bye-bye precious…
Method 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 $)
Method 3
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
Method 4
The Seiji Adachi fix which he calls temporary works for me well https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=906766
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0