7

Playing around in my system, I stumbled upon

~$ echo $XDG_DATA_DIRS
/usr/share/ubuntustudio:/usr/share/xfce4:/usr/local/share:/usr/share:/var/lib/snapd/desktop:/usr/share

Asking myself why /usr/share is twice in the path I found out that the following snippet in /etc/alternatinves/x-session-manager which is a link to /usr/bin/startxfce4 is responsible:

#!/bin/sh
.
.
.
if test "x$XDG_DATA_DIRS" = "x"
then
  if test "x/usr/share" = "x/usr/local/share" -o "x/usr/share" = "x/usr/share"; then
    XDG_DATA_DIRS="/usr/local/share:/usr/share"
  else
    XDG_DATA_DIRS="/usr/share:/usr/local/share:/usr/share"
  fi
else
  XDG_DATA_DIRS="$XDG_DATA_DIRS:/usr/share"
fi
export XDG_DATA_DIRS
.
.
.

When I look at the line

if test "x/usr/share" = "x/usr/local/share" -o "x/usr/share" = "x/usr/share"; then

I have difficulties to understand this if-statement, for me it looks like a comparison of strings where the first one is always false and the second one is always true.

Combined with a logical or the test always evaluates to true, so I could shorten the line to if true; then or I could say I don't need an if-statement at all.

Where is my mistake? Or is it written like this to confuse beginners like me?

2

You are right, the command

test "x/usr/share" = "x/usr/local/share" -o "x/usr/share" = "x/usr/share"

returns true (0) always.

It looks like if the file in question was generated from a more generic version but the way of generation was not optimal. The script should either ask for actual paths each time or keep just the relevant branch in the generated file.

However, this particular file comes from a package – not being generated on your machine. This is likely something to be fixed/improved… You can file a bug on Xfce Bugzilla (if it’s not present there already) or fix it yourself. You can clone the Git repository for Xfce4 session, you can also get in touch with Xfce4 developers using their mailing list. Good luck with improving the code!

1

The script /usr/bin/startxfce4 seems to be generated by a parser, we can see that when we look at the source code, let's take a look at the corresponding snippet:

if test "x$XDG_DATA_DIRS" = "x"
then
  if test "x@_datadir_@" = "x/usr/local/share" -o "x@_datadir_@" = "x/usr/share"; then
    XDG_DATA_DIRS="/usr/local/share:/usr/share"
  else
    XDG_DATA_DIRS="@_datadir_@:/usr/local/share:/usr/share"
  fi
else
  XDG_DATA_DIRS="$XDG_DATA_DIRS:@_datadir_@"
fi
export XDG_DATA_DIRS

Here we can see the meaning of this if-block, the developers give package-maitainers the opportunity to add a custom path to XDG_DATA_DIRS by parsing the desired path to the script and substituting the string @_datadir_@ with this path.

This will work perfectly, if a path is parsed which is not contained in XDG_DATA_DIRS at the time the script runs, but it will result in the same path appearing twice in XDG_DATA_DIRS if we parse a path which already exists in XDG_DATA_DIRS at the time the script runs.

This could be avoided by not parsing the standard XDG-folders (/usr/share, /usr/local/share) to the script, I don't know if that is possible though.

Another solution is to change the source code to

if test "x$XDG_DATA_DIRS" = "x"
then
  if test "x@_datadir_@" = "x/usr/local/share" -o "x@_datadir_@" = "x/usr/share"; then
    XDG_DATA_DIRS="/usr/local/share:/usr/share"
  else
    XDG_DATA_DIRS="@_datadir_@:/usr/local/share:/usr/share"
  fi
else
  if test "x@_datadir_@" != "x/usr/local/share" -a "x@_datadir_@" != "x/usr/share"; then
    XDG_DATA_DIRS="$XDG_DATA_DIRS:@_datadir_@"
  fi
fi
export XDG_DATA_DIRS

That would cover only the directories /usr/share and /usr/local/share though and one should indeed check if @_datadir_@ already exists in XDG_DATA_DIRS or not, but I don't know who to do that, my knowledge ends here.

In addition:

The same applies to this part of the script:

if test "x$XDG_CONFIG_DIRS" = "x"
then
  if test "x@_sysconfdir_@" = "x/etc"; then
    XDG_CONFIG_DIRS="/etc/xdg"
  else
    XDG_CONFIG_DIRS="/etc/xdg:@_sysconfdir_@/xdg"
  fi
else
  XDG_CONFIG_DIRS="$XDG_CONFIG_DIRS:@_sysconfdir_@/xdg"
fi
export XDG_CONFIG_DIRS

When we parse /etc/xdg/ to substitute @_sysconfdir_@ it leeds to a duplicated path (/etc/xdg:/etc/xdg in XDG_CONFIG_DIRS.

Greetings

I'm an end user, far from being a developer, so I'm unable to solve the problem completely. Thanks to dessert and melebius who pushed me in the right direction, at least I understand this if-then-statement now.

I believe that there is no harm in having a path twice in this environment variables, so I'll refrain from reporting a bug. Let the developers do more valuable things.

My personal solution

I changed the lines 67-89 in /usr/bin/startxfce4

if test "x$XDG_DATA_DIRS" = "x"
then
  if test "x/usr/share" = "x/usr/local/share" -o "x/usr/share" = "x/usr/share"; then
    XDG_DATA_DIRS="/usr/local/share:/usr/share"
  else
    XDG_DATA_DIRS="/usr/share:/usr/local/share:/usr/share"
  fi
else
  XDG_DATA_DIRS="$XDG_DATA_DIRS:/usr/share"
fi
export XDG_DATA_DIRS

if test "x$XDG_CONFIG_DIRS" = "x"
then
  if test "x/etc" = "x/etc"; then
    XDG_CONFIG_DIRS="/etc/xdg"
      else
   XDG_CONFIG_DIRS="/etc/xdg:/etc/xdg"
  fi
else
  XDG_CONFIG_DIRS="$XDG_CONFIG_DIRS:/etc/xdg"
fi
export XDG_CONFIG_DIRS

to

if test "x$XDG_DATA_DIRS" = "x"
then
  XDG_DATA_DIRS="/usr/local/share:/usr/share"
fi
export XDG_DATA_DIRS

if test "x$XDG_CONFIG_DIRS" = "x"
then
  XDG_CONFIG_DIRS="/etc/xdg"
fi
export XDG_CONFIG_DIRS

Of course, I backed up the original file first.

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.