Linux C++ 检测用户的 shell(csh、bash 等)

4
我有一个 C++ 应用程序,需要使用系统调用执行特定于 shell 的命令。是否有一种方法来检测用户正在运行的 shell?(Csh/Bash 等)。感谢您。
更详细一点,我正在尝试处理一些代码,通过 system 分叉出一个 rsh 调用,其中一系列的命令使用了 setenv,但在 bash 中不起作用。我想检测系统是 csh 还是 bash,并相应地重新编写这些调用。

你可以在/etc/passwd中查找,例如:cat /etc/passwd | grep user | cut -d: -f7 - Super-intelligent Shade
@InnocentBystander 然后呢?当前的shell在那里吗?没有吗? - deviantfan
@ssube,不是这样的。在这种情况下,请使用:getent passwd <user> | cut -d: -f7。如果用户在LDAP和passwd中都有记录,则可能需要使用headtail - Super-intelligent Shade
1
不要使用(不安全的)rsh命令,而是使用fork然后execve它。 - Basile Starynkevitch
我从未听说过“etc” shell。 - Alexander Stohr
显示剩余9条评论
3个回答

2

使用geteuid获取用户ID,使用getpwuid获取该ID的用户数据库条目,其中包含shell信息,不能释放。因此,它可以分解为以下步骤:

getpwuid(geteuid())->pw_shell

最简工作示例:

#include <pwd.h>
#include <unistd.h>
#include <stdio.h>

int main (int argc, const char* argv[]) {
    printf("%s\n", getpwuid(geteuid())->pw_shell);
    return 0;
}

1
不知道这是否有任何用处。
#include <iostream>
#include <cstdlib>     /* getenv */

int main ()
{
  char* Shell;
  Shell = getenv ("SHELL");
  if (Shell!=NULL)
  std::cout << Shell << std::endl;
  return 0;
}

会输出类似以下内容的东西。
/bin/bash

Getenv返回一个包含环境变量值的C字符串。

Link:http://www.cplusplus.com/reference/cstdlib/getenv/


编译正常。路径返回 null,这很奇怪。 - Jeef
@Jeef 如果您在命令行上键入 env,其中一个变量是 SHELL 吗?如果不是,是否有类似的东西? - user3442743
不,它应该在那里,而且getenv似乎是正确的答案...我需要更深入地研究我的特定构建。也许现在是进行make clean的时候了。 - Jeef
这并不保证可行,很可能只适用于Bash。 - ManuelSchneid3r

0

我试图获取BASH_VERSION/ZSH_VERSION/...环境变量,但它们未导出到子进程; /etc/passwd 给出登录 shell,因此我发现获取当前 shell 的唯一方法是:

const char* get_process_name_by_pid(const int pid)
{
    char* name = (char*)calloc(256,sizeof(char));
    if(name){
        sprintf(name, "/proc/%d/cmdline",pid);
        FILE* f = fopen(name,"r");
        if(f){
            size_t size = fread(name, sizeof(char), 256, f);
            if(size>0){
                if('\n'==name[size-1])
                    name[size-1]='\0';
            }
            fclose(f);
        }
    }
    return name;
}

bool isZshParentShell() {
    pid_t parentPid=getppid();
    const char* cmdline=get_process_name_by_pid(parentPid);
    return cmdline && strstr(cmdline, "zsh");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接