【问题标题】:How to check if a specific program (shell command) is available on a Linux in D?如何检查特定程序(shell 命令)在 D 中的 Linux 上是否可用?
【发布时间】:2016-01-08 22:22:11
【问题描述】:

我正在尝试编写一个类似脚本的 D 程序,它会根据用户系统上某些工具的可用性而具有不同的行为。

我想测试给定程序是否可以从命令行使用(在本例中为 unison-gtk)或者是否已安装(我只关心使用 apt 的 Ubuntu 系统)

【问题讨论】:

    标签: shell d


    【解决方案1】:
    man which
    man whereis
    man find
    man locate
    

    【讨论】:

    • 我非常了解这些工具。我在问是否有解决问题的native D 解决方案(库)。
    • 也许你应该简单地检查一下它的文件是否存在?
    • @user1432751 这实际上就是我对答案所做的。诀窍是检查文件是否存在于默认搜索路径中(并可能检查-version 的输出),因为可以将程序安装在不同的位置。
    • which 实际上有点“原生”工具。它基本上会遍历 PATH 中列出的目录并检查可执行文件是否存在。唯一的区别是它为您提供了所有选择,而当您尝试使用program-name 运行程序时,例如 Linux,它会执行它首先找到的可执行文件。
    【解决方案2】:

    为了记录,使用例如四处走走tryRun:

    bool checkIfUnisonGTK() 
    {
       import scriptlike;
       return = tryRun("unison-gtk -version")==0;
    }
    

    【讨论】:

    • 我认为这是最好的方法。你想要做的是运行一个程序......所以只需运行该程序,看看会发生什么。试图深入研究文件是否存在或是否安装了包,诸如此类的事情就像在你真的应该只关心接口时深入研究实现细节。所以我认为这根本不是一种解决方法,我认为这是正确的解决方案。
    【解决方案3】:

    不可能有任何«native D解决方案»,因为您试图检测系统环境中的某些东西,而不是您的程序本身。所以没有解决方案是“原生的”。

    顺便说一句,如果你真的只关心 Ubuntu,你可以解析命令 dpkg --status unison-gtk 的输出。但对我来说,它会打印出package 'unison-gtk' is not installed and no information is available(我想我没有启用你拥有的一些存储库)。所以我认为 C1sc0 的答案是最通用的:你应该尝试运行 which unison-gtk (或任何你想运行的命令)并检查它是否打印任何东西。即使用户从存储库以外的任何地方安装了 unison-gtk,这种方式也可以工作,例如已从源代码构建它或将二进制文件直接复制到 /usr/bin 等。

    【讨论】:

    • 这种方法在通过手动编译安装应用程序时严重失败,然后安装(典型的configure --prefix=/usr/ocal; make; sudo make install)...
    • 为什么?如果一个程序在PATH 内,它也应该对which 可见。如果没有,那么我们无论如何都无法运行它(如果用户不会明确设置二进制文件的路径)。
    • 其实我指的是你评论的前半部分(dpkg --status)……我没有注意到你提到哪个工具的部分……
    【解决方案4】:

    我建议你获取 PATH 环境变量,而不是 tryRun,解析它(解析它很简单),然后在这些目录中查找特定的可执行文件:

    module which1;
    
    import std.process;   // environment
    import std.algorithm; // splitter
    import std.file;      // exists
    
    import std.stdio;
    
    /**
     * Use this function to find out whether given executable exists or not.
     * It behaves like the `which` command in Linux shell.
     * If executable is found, it will return absolute path to it, or an empty string.
     */
    string which(string executableName) {
        string res = "";
        auto path = environment["PATH"];
        auto dirs = splitter(path, ":");
        foreach (dir; dirs) {
            auto tmpPath = dir ~ "/" ~ executableName;
            if (exists(tmpPath)) {
                return tmpPath;
            }
        }
    
        return res;
    } // which() function
    
    int main(string[] args) {
        writeln(which("wget")); // output: /usr/bin/wget
        writeln(which("non-existent")); // output: 
    
        return 0;
    }
    

    which() 函数的一个自然改进是检查 tmpPath 是否为可执行文件,并且仅在找到具有给定名称的可执行文件时返回...

    【讨论】:

    • 这肯定是更好的解决方案。您甚至可以使用 std.path.pathSeparator 变量在 Windows 上完成这项工作,该变量在 Linux 上是“:”,而“;”在窗户上..
    【解决方案5】:

    Linux command to list all available commands and aliases

    简而言之:运行auto r = std.process.executeShell("compgen -c")r.output 中的每一行都是一个可用的命令。需要安装 bash。

    【讨论】:

    • 酷!我不知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2020-07-10
    • 2011-11-05
    • 2012-12-12
    相关资源
    最近更新 更多