检查程序是否安装在C中

检查程序是否安装在C中,c,C,我想找到一种方法来确定程序是否使用C gnu11标准安装,例如,如果使用C中的system函数执行命令“Rscript”是否有效 我不是经过培训的程序员,所以我不确定我是否使用了正确的搜索词 我想要相当于C语言的 con@con-Inspiron-3521:~/Scripts$ which Rscript /usr/bin/Rscript 在C语言中如何实现这一点?根据@Paul\R的回答,我得出了以下结论: #include <stdio.h> #include <lin

我想找到一种方法来确定程序是否使用C gnu11标准安装,例如,如果使用C中的
system
函数执行命令“Rscript”是否有效

我不是经过培训的程序员,所以我不确定我是否使用了正确的搜索词

我想要相当于C语言的

con@con-Inspiron-3521:~/Scripts$ which Rscript 
/usr/bin/Rscript

在C语言中如何实现这一点?

根据@Paul\R的回答,我得出了以下结论:

#include <stdio.h>
#include <linux/limits.h>//PATH_MAX definition
#include <string.h>//strlen
#include <stdbool.h>

const bool is_program_installed( const char *restrict COMMAND) {

    FILE *restrict fp;
    fp = popen(COMMAND, "r");
    if (fp == NULL) {
        pclose(fp);
        return false;
    }
    char path[PATH_MAX];
    bool return_value = false;
    while (fgets(path, PATH_MAX, fp) != NULL) {
         if (strlen(path) > 0) {
            return_value = true;
            break;
         }
    }
    pclose(fp);
    return return_value;
}

int main() {

    printf("ls  %s\n", is_program_installed("ls") ? "true" : "false");
    printf("not_program %s\n", is_program_installed("not_program") ? "true" : "false");
    return 0;
}
#包括
#包括//路径\最大定义
#包括//strlen
#包括
const bool已安装程序(const char*restrict命令){
文件*限制fp;
fp=popen(命令,“r”);
如果(fp==NULL){
pclose(fp);
返回false;
}
字符路径[path_MAX];
bool return_value=false;
while(fgets(path,path_MAX,fp)!=NULL){
如果(strlen(路径)>0){
返回值=真;
打破
}
}
pclose(fp);
返回_值;
}
int main(){
printf(“ls%s\n”,是否安装了程序(“ls”)?“true”:“false”);
printf(“非程序%s\n”,是否已安装(“非程序”)?“true”:“false”);
返回0;
}

如果不打印“sh:1:not_program:not found”(sh:1:not_program:not found)(程序:not found)(未找到)就可以了,但这已经足够好了。

通过类似的努力,您只需解析
路径
变量,并检查给定的文件是否存在且是否可执行:

#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

bool can_run_command(const char *cmd) {
    if(strchr(cmd, '/')) {
        // if cmd includes a slash, no path search must be performed,
        // go straight to checking if it's executable
        return access(cmd, X_OK)==0;
    }
    const char *path = getenv("PATH");
    if(!path) return false; // something is horribly wrong...
    // we are sure we won't need a buffer any longer
    char *buf = malloc(strlen(path)+strlen(cmd)+3);
    if(!buf) return false; // actually useless, see comment
    // loop as long as we have stuff to examine in path
    for(; *path; ++path) {
        // start from the beginning of the buffer
        char *p = buf;
        // copy in buf the current path element
        for(; *path && *path!=':'; ++path,++p) {
            *p = *path;
        }
        // empty path entries are treated like "."
        if(p==buf) *p++='.';
        // slash and command name
        if(p[-1]!='/') *p++='/';
        strcpy(p, cmd);
        // check if we can execute it
        if(access(buf, X_OK)==0) {
            free(buf);
            return true;
        }
        // quit at last cycle
        if(!*path) break;
    }
    // not found
    free(buf);
    return false;
}
#包括
#包括
#包括
#包括
bool can_run_命令(const char*cmd){
if(strchr(cmd,“/”)){
//如果cmd包含斜杠,则不必执行路径搜索,
//直接检查它是否可执行
返回访问(cmd,X_OK)==0;
}
const char*path=getenv(“路径”);
如果(!path)返回false;//出现严重错误。。。
//我们确信我们不再需要缓冲区了
char*buf=malloc(strlen(path)+strlen(cmd)+3);
如果(!buf)返回false;//实际上无用,请参见注释
//循环,只要路径中有要检查的内容
对于(;*path;++path){
//从缓冲区的开头开始
char*p=buf;
//在buf中复制当前路径元素
对于(;*path&&*path!=':';++path,++p){
*p=*路径;
}
//空路径项被视为“.”
如果(p==buf)*p++=';
//斜杠和命令名
如果(p[-1]!='/')*p++='/';
strcpy(p,cmd);
//检查我们是否可以执行它
if(访问(buf,X_OK)==0){
免费(buf);
返回true;
}
//在最后一个周期退出
如果(!*路径)中断;
}
//找不到
免费(buf);
返回false;
}
该程序可能在
路径
环境变量中指定的任何目录中搜索文件

有很多方法可以做到这一点,这就是其中之一

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stddef.h>

#include <sys/stat.h>

int
main(int argc, char *argv[])
{
    const char *head;
    const char *command;
    size_t length;

    if (argc < 2) {
        fprintf(stderr, "insufficient number of arguments\n");
        return -1;
    }

    command = argv[1];
    length = strlen(command);
    // Get the PATH environment variable
    head = getenv("PATH");
    if (head == NULL) {
        fprintf(stderr, "the PATH variable was not set, what?\n");
        return -1;
    }
    // Find the first separator
    while (*head != '\0') {
        struct stat st;
        ptrdiff_t dirlen;        
        const char *tail;
        char *path;
        // Check for the next ':' if it's not found
        // then get a pointer to the null terminator
        tail = strchr(head, ':');
        if (tail == NULL)
            tail = strchr(head, '\0');
        // Get the length of the string between the head
        // and the ':'
        dirlen = tail - head;
        // Allocate space for the new string
        path = malloc(length + dirlen + 2);
        if (path == NULL)
            return -1;
        // Copy the directory path into the newly
        // allocated space
        memcpy(path, head, dirlen);
        // Append the directory separator
        path[dirlen] = '/';
        // Copy the name of the command            
        memcpy(path + dirlen + 1, command, length);
        // `null' terminate please
        path[dirlen + length + 1] = '\0';
        // Check if the file exists and whether it's
        // executable
        if ((stat(path, &st) != -1) && (S_ISREG(st.st_mode) != 0)) {
            if ((st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) {                
                fprintf(stdout, "found `%s' but it's not executable\n", path);
            } else {
                fprintf(stdout, "found at: %s\n", path);
            }                
        }
        // Don't forget to free!
        free(path);
        // Point to the next directory
        head = tail + 1;
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
int
main(int argc,char*argv[])
{
常量字符*头;
const char*命令;
尺寸与长度;
如果(argc<2){
fprintf(stderr,“参数数量不足”);
返回-1;
}
command=argv[1];
长度=strlen(命令);
//获取PATH环境变量
head=getenv(“路径”);
if(head==NULL){
fprintf(stderr,“未设置路径变量,什么?\n”);
返回-1;
}
//找到第一个分隔符
而(*head!='\0'){
结构统计;
ptrdiff_t dirlen;
常量字符*尾部;
字符*路径;
//如果找不到,请检查下一个“:”
//然后获取指向空终止符的指针
尾部=strchr(头部“:”);
if(tail==NULL)
尾部=strchr(头部,'\0');
//获取头部之间的字符串长度
//还有“:”
dirlen=尾部-头部;
//为新字符串分配空间
路径=malloc(长度+dirlen+2);
if(路径==NULL)
返回-1;
//将目录路径复制到新目录中
//分配的空间
memcpy(路径、头部、方向);
//附加目录分隔符
路径[dirlen]='/';
//复制命令的名称
memcpy(路径+dirlen+1,命令,长度);
//“null”请终止
路径[dirlen+length+1]='\0';
//检查该文件是否存在以及是否存在
//可执行
如果((状态(路径和st)!=1)和(&U ISREG(st.st模式)!=0)){
如果((st.st_模式和(S|uixusr | S|uixgrp | S|uixoth))==0{
fprintf(stdout,“找到“%s”,但它不是可执行文件\n”,路径);
}否则{
fprintf(stdout,“位于:%s\n”,路径);
}                
}
//别忘了自由!
自由(路径);
//指向下一个目录
头=尾+1;
}
返回0;
}
一般来说,相同的算法

  • 获取
    PATH
    环境变量,该变量由一系列目录路径组成,路径之间用
    字符分隔
  • 通过迭代获取序列中的每个目录路径,这是可以通过多种方式实现的
  • 检查一下

    • 该文件已存在
    • 具有调用方的执行权限

  • 好的,您可以随时运行
    哪个Rscript
    并捕获输出。我不理解您的问题,您想知道是什么编译了这个程序吗?或者是否安装了该程序?或者你只是想在C中运行bash命令?@SanchkeDellowar我想看看我是否能在C程序中执行“Rscript”。据我所知,没有可移植的C方法可以做到这一点。您可能想看看是否有与POSIX等效的版本,因为它仍然具有良好的可移植性。您是否应该使用
    “which”
    预先使用
    命令
    ?否则,您将运行并获取命令的输出,而不是其p