2015-10-11 7 views
1

Я пытаюсь написать программу D, подобную сценарию, которая будет иметь другое поведение, основанное на наличии определенных инструментов в пользовательской системе.Как проверить, доступна ли какая-либо программа (команда оболочки) на Linux в D?

Я хотел бы проверить, является ли данная программа доступна из командной строки (в данном случае это unison-gtk), или если он установлен (я забочусь только о системах Ubuntu, которые используют apt)

ответ

0
man which 
man whereis 
man find 
man locate 
+0

Я знаю эти инструменты очень хорошо. Я спрашиваю, есть ли решение * native * D (библиотека), которое решает проблему. –

+0

Возможно, вам стоит просто проверить, существует ли файл? –

+0

@ user1432751 Это действительно то, что я сделал с моим ответом. Хитрость заключается в том, чтобы проверить, существует ли файл в пути поиска по умолчанию (и, возможно, проверять вывод «-version»), поскольку он может быть установлен в разных местах. –

2

Для записи есть прогулка вокруг, например, tryRun:

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

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

1

Там не может быть «родным 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 и т. д.

+0

Этот подход эпично терпит неудачу, когда приложение установлено с помощью ручной компиляции, а затем установка (типичный 'configure -prefix =/usr/ocal; make; sudo make install') ... – DejanLekic

+0

Почему? Если программа находится в 'PATH', она также должна быть видна' which'. А если нет, то мы все равно не сможем его запустить (если пользователь не будет явно указывать путь к двоичному файлу). –

+0

Собственно, я имел в виду первую половину вашего комментария (dpkg --status) ... Я не заметил той части, где вы упомянули, какой инструмент ... – DejanLekic

2

Вместо 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 исполняемый файл, или нет, и вернуться только тогда, когда он нашел исполняемый с данным именем ...

+2

Это, безусловно, лучшее решение. Вы даже можете сделать эту работу над окнами, используя переменную std.path.pathSeparator, которая является «:» на linux и «;» на окнах .. –