【问题标题】:Portable way to find out if a command exists (C/C++)找出命令是否存在的便携式方法 (C/C++)
【发布时间】:2023-04-08 00:51:01
【问题描述】:

C 标准库提供函数systempopen 来运行命令。但是有没有一种可移植的方法来检测命令是否存在?

【问题讨论】:

  • 通过“命令”,看起来您的意思是“用户机器上的另一个程序”?你能确认这是你的意思吗?

标签: c++ system popen


【解决方案1】:

对于 POSIX 系统,我发现它工作得很好(在这个例子中我正在检查 avconv):

if (system("which avconv > /dev/null 2>&1")) {
    // Command doesn't exist...
} else {
    // Command does exist, do something with it...
}

重定向到 /dev/null 只是为了避免将任何内容打印到标准输出。它仅依赖于 which 命令的退出值。

【讨论】:

  • 重定向是缺少其他答案的原因。 +1 避免哪个输出
【解决方案2】:

这是一种扫描PATH变量中存储的所有路径的方法,扫描mathsat可执行文件:

#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <iostream>

using namespace std;

int main ()
{
  struct stat sb;
  string delimiter = ":";
  string path = string(getenv("PATH"));
  size_t start_pos = 0, end_pos = 0;

  while ((end_pos = path.find(':', start_pos)) != string::npos)
    {
      string current_path =
        path.substr(start_pos, end_pos - start_pos) + "/mathsat";

      if ((stat(mathsat_path.c_str(), &sb) == 0) && (sb.st_mode & S_IXOTH))
        {
          cout << "Okay" << endl;
          return EXIT_SUCCESS;
         }

      start_pos = end_pos + 1;
     }

  return EXIT_SUCCESS;
}

【讨论】:

  • 这很棒。但它排除了路径中的最后一项。
【解决方案3】:

虽然我不认为有一种完全可移植的方式来做到这一点(有些系统甚至不支持命令解释器),但如果在运行命令时没有错误,system() 会返回 0。我想你可以尝试运行你的命令,然后检查系统的返回值。

要检查命令解释器是否可用,请调用 system( NULL ) 并检查非零值。

【讨论】:

    【解决方案4】:

    不,没有任何标准的 C 函数。

    仅 Unix 的解决方案是将 getenv("PATH") 拆分为 :(冒号),并尝试在目录中找到可执行的命令(使用 stat 函数)。

    【讨论】:

    • +1。在 Windows 上,有点不同:break on ";"不是“:”,您需要检查以(至少)“.exe”、“.com”和“.bat”结尾的文件。事实上,它比这更棘手——我记得,cmd.exe 首先在所有目录中搜索 .com 文件,然后在所有目录中搜索 .exe 文件,等等。不幸的是,我不记得细节了,但它 与 CreateProcess() 使用的顺序不同。
    • 在 Windows 上,可执行的扩展名更多,例如 .pif、.lnk、.vbs、.scr 等。最好找到一个 API 调用来列出所有这些,而不是硬编码他们。
    猜你喜欢
    • 2013-08-08
    • 1970-01-01
    • 2011-03-01
    • 2011-01-26
    • 2012-11-20
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多