Что означает это утверждение «если тогда»?

Играя в своей системе, я наткнулся на

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

Спрашивая себя, почему /usr/share дважды в пути, я обнаружил, что следующий фрагмент в /etc/alternatinves/x-session-manager, который является ссылкой на /usr/bin/startxfce4 отвечает:

#!/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
.
.
.

Когда я смотрю на строку

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

, мне трудно понять это выражение if, для меня это выглядит как сравнение строк, где первый один всегда ложный, а второй всегда истинный.

В сочетании с логическим or тест всегда оценивается как true , поэтому я мог бы сократить строку до if true; then или я мог бы сказать, что мне вообще не нужен оператор if.

1114 Где моя ошибка? Или это написано так, чтобы сбить с толку начинающих, как я?

7
задан 29 August 2019 в 16:22

2 ответа

Вы правы, команда

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

возвращается верный (0) всегда.

Похоже, был ли рассматриваемый файл сгенерирован от более универсальной версии, но способ поколения не был оптимален. Сценарий должен или попросить фактические пути каждый раз или сохранить просто соответствующее ответвление в сгенерированном файле.

Однако этот конкретный файл прибывает из пакета – не сгенерированный на Вашей машине. Это вероятно что-то, чтобы фиксироваться/улучшаться …, можно зарегистрировать ошибку на Bugzilla Xfce (если это уже не присутствует там), или зафиксируйте его сами. Можно клонировать репозиторий Мерзавца для сессии Xfce4, можно также связаться с разработчиками Xfce4, использующими их список рассылки. Удача с улучшением кода!

2
ответ дан 23 November 2019 в 06:50

Сценарий /usr/bin/startxfce4 кажется, сгенерирован синтаксическим анализатором, мы видим, что, когда мы смотрим на исходный код, давайте смотреть на соответствующий отрывок:

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

Здесь мы видим значение этого если-блока, разработчики дают пакету-maitainers возможность добавить пользовательский путь к XDG_DATA_DIRS путем парсинга желаемого пути к сценарию и замены строкой @_datadir_@ с этим путем.

Это будет работать отлично, если путь будет проанализирован, который не содержится в XDG_DATA_DIRS в то время выполнения сценария, но это приведет к тому же пути, появляющемуся дважды в XDG_DATA_DIRS если мы анализируем путь, который уже существует в XDG_DATA_DIRS в то время выполнения сценария.

Этого можно было избежать, не анализируя стандартные XDG-папки (/usr/share, /usr/local/share) к сценарию я не знаю, возможно ли это все же.

Другое решение состоит в том, чтобы изменить исходный код на

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

Это покрыло бы только каталоги /usr/share и /usr/local/share хотя и нужно действительно проверить если @_datadir_@ уже существует в XDG_DATA_DIRS или нет, но я не знаю, кто сделать это, мое знание заканчивается здесь.

Кроме того:

То же относится к этой части сценария:

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

Когда мы анализируем /etc/xdg/ занимать место @_sysconfdir_@ это Лидс к дублированному пути (/etc/xdg:/etc/xdg в XDG_CONFIG_DIRS.

Поздравления

Я - конечный пользователь, далекий от того, чтобы быть разработчиком, таким образом, я не могу решить проблему полностью. Благодаря десерту и melebius, кто продвинул меня в правильном направлении, по крайней мере, я понимаю этот if-then-statement теперь.

Я полагаю, что нет никакого вреда в наличии пути дважды в этом переменные среды, таким образом, я воздержусь от сообщения об ошибке. Позвольте разработчикам сделать более ценные вещи.

Мое персональное решение

Я изменил строки 67-89 в /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

кому:

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

Конечно, я создал резервную копию исходного файла сначала.

1
ответ дан 23 November 2019 в 06:50

Другие вопросы по тегам:

Похожие вопросы: