【发布时间】:2016-01-08 22:22:11
【问题描述】:
我正在尝试编写一个类似脚本的 D 程序,它会根据用户系统上某些工具的可用性而具有不同的行为。
我想测试给定程序是否可以从命令行使用(在本例中为 unison-gtk)或者是否已安装(我只关心使用 apt 的 Ubuntu 系统)
【问题讨论】:
我正在尝试编写一个类似脚本的 D 程序,它会根据用户系统上某些工具的可用性而具有不同的行为。
我想测试给定程序是否可以从命令行使用(在本例中为 unison-gtk)或者是否已安装(我只关心使用 apt 的 Ubuntu 系统)
【问题讨论】:
man which
man whereis
man find
man locate
【讨论】:
-version 的输出),因为可以将程序安装在不同的位置。
which 实际上是有点“原生”工具。它基本上会遍历 PATH 中列出的目录并检查可执行文件是否存在。唯一的区别是它为您提供了所有选择,而当您尝试使用program-name 运行程序时,例如 Linux,它会执行它首先找到的可执行文件。
为了记录,使用例如四处走走tryRun:
bool checkIfUnisonGTK()
{
import scriptlike;
return = tryRun("unison-gtk -version")==0;
}
【讨论】:
不可能有任何«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 可见。如果没有,那么我们无论如何都无法运行它(如果用户不会明确设置二进制文件的路径)。
我建议你获取 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 是否为可执行文件,并且仅在找到具有给定名称的可执行文件时返回...
【讨论】:
Linux command to list all available commands and aliases
简而言之:运行auto r = std.process.executeShell("compgen -c")。 r.output 中的每一行都是一个可用的命令。需要安装 bash。
【讨论】: