这个“如果-那么”语句是什么意思?

这个“如果-那么”语句是什么意思?

在我的系统中玩耍时,我偶然发现了

~$ 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测试总是评估为真的,所以我可以将这行代码缩短为 if true; then,或者可以说我根本不需要 if 语句。

我的错误在哪里?还是这样写是为了混淆像我这样的初学者?

答案1

你是对的,命令

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

始终返回 true (0)。

看起来,如果所讨论的文件是从更通用的版本生成的,但生成方式不是最佳的。脚本应该每次都询问实际路径,或者只保留生成的文件中的相关分支。

然而,这特定文件来自包– 无法在您的机器上生成。这可能需要修复/改进…您可以在Xfce 漏洞(如果它还没有出现在那里)或者自己修复。你可以克隆Xfce4 会话的 Git 存储库,您还可以使用他们的邮件列表。祝你改进代码顺利!

答案2

该脚本/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

XDG_DATA_DIRS这里我们可以看到这个 if-block 的含义,开发人员通过解析脚本所需的路径并@_datadir_@用该路径替换字符串,为包维护者提供了添加自定义路径的机会。

如果解析的路径在脚本运行时不包含在内,那么这将完美地工作,但是如果我们解析的路径在脚本运行时已经存在XDG_DATA_DIRS,则会导致相同的路径出现两次。XDG_DATA_DIRSXDG_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/xdgXDG_CONFIG_DIRS.

问候

我是一名终端用户,远非开发人员,因此我无法完全解决这个问题。感谢甜点梅勒比乌斯谁把我推向了正确的方向,至少现在我理解了这个“如果-那么”的陈述。

我认为在这个环境变量中出现两次路径并没有什么坏处,所以我不会报告错误。让开发人员做更多有价值的事情。

我的个人解决方案

我改变了第 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

当然,我先备份了原文件。

相关内容