除了/ etc / passwd以外还有另外一种方法来获取用户shell吗?

时间:2015-11-03 23:42:05

标签: shell unix

我想使用某种shell查找服务器上的所有用户。例如,我想在登录时使用/ bin / csh计算用户数。但我没有/ etc / passwd文件的任何权限。命令getent也不起作用。我的问题有可能解决方案吗?

1 个答案:

答案 0 :(得分:1)

是。标准API调用可用于检索/etc/passwd条目,这些条目可配置为从/etc/passwd以外的来源检索它们(如果您的系统' NSS配置是合适的)。来自man 3 getpwent

#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwent(void);
     

getpwent()函数返回一个指向结构的指针,该结构包含来自密码数据库的记录的分解字段(例如,本地密码文件/ etc / passwd,NIS和LDAP)。第一次调用getpwent()时,它返回第一个条目;之后,它返回连续的条目。

如果您在Linux(或具有类似NSS堆栈的其他操作系统)上执行此操作并想要一个命令行工具,我建议getent

$ getent passwd username
username:x:1000:1000::/home/cduffy:/bin/bash

...然后,只提取shell:

$ IFS=: read username _ uid gid _ homedir shell _ < <(getent passwd username)
$ print '%s\n' "$shell"
/bin/bash

如果您需要使用getpwent()而不使用getent的工具,请考虑perl。引自http://www.tutorialspoint.com/perl/perl_getpwent.htm

#!/usr/bin/perl

while(($name, $passwd, $uid, $gid, $quota,
  $comment, $gcos, $dir, $shell) = getpwent()){
   print "Name = $name\n";
   print "Password = $passwd\n";
   print "UID = $uid\n";
   print "GID = $gid\n";
   print "Quota = $quota\n";
   print "Comment = $comment\n";
   print "Gcos = $gcos\n";
   print "HOME DIR = $dir\n";
   print "Shell = $shell\n";
}

顺便说一句:/etc/passwd不可能是世界可读的,这是非常不同寻常的;几十年来,机密信息已从那里转移到/etc/shadow。如果安装了getent但运行时出现错误而失败,则NSS堆栈可能配置为期望可读/etc/passwd,并且修改它的任何管理员或脚本都会破坏该约束,从而破坏您的操作系统。 / p>