我正在尝试编写一个类似脚本的D程序,这将根据用户系统上某些工具的可用性有不同的行为。
我想测试一个给定的程序是否可以从命令行获得(在这种情况下是unison-gtk
),或者它是否已经安装(我只关心Ubuntu系统,它使用apt
)
为记录,有一个走动使用例如tryRun
:
bool checkIfUnisonGTK()
{
import scriptlike;
return = tryRun("unison-gtk -version")==0;
}
代替tryRun,我建议您获取PATH环境变量,解析它(解析它很简单),并在这些目录中查找特定的可执行文件:
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是否是可执行文件,并仅在发现可执行文件具有给定名称时返回
不可能有任何"本地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
等。
Linux命令列出所有可用的命令和别名
简而言之:运行auto r = std.process.executeShell("compgen -c")
。r.output
中的每一行都是一个可用的命令。需要安装bash
man which
man whereis
man find
man locate