27 个版本
使用旧的 Rust 2015
0.11.0 | 2020 年 10 月 8 日 |
---|---|
0.10.0 | 2020 年 4 月 7 日 |
0.9.1 | 2019 年 3 月 16 日 |
0.8.1 | 2018 年 11 月 26 日 |
0.1.1 | 2014 年 12 月 12 日 |
在 Unix API 中排名 699
每月下载量 145,054
在 不到 155 个crate中使用
81KB
1K SLoC
rust-users

这是一个用于访问 Unix 用户和组的库。它支持获取系统用户和组,将它们存储在缓存中,并创建您自己的模拟表。
查看 Rustdoc
安装
此crate与 Cargo 一起工作。将以下内容添加到您的 Cargo.toml
依赖关系部分
[dependencies]
users = "0.11"
此crate测试的最早的 Rust 版本是 Rust v1.31.0。
使用方法
在 Unix 中,每个用户都有一个唯一的 用户ID,每个进程都有一个 实际用户ID,它表示该进程正在使用哪个用户的权限。此外,用户可以是 组 的成员,组也有名称和ID。此功能在 libc 中公开,它是 C 标准库,但作为不安全的 Rust 接口。此包装库提供了一个安全接口,使用 User
和 Group
类型以及 get_user_by_id
等函数,而不是底层指针和字符串。它还提供了基本的缓存功能。
它(目前)不提供 编辑 功能;返回的值是只读的。
用户
函数 get_current_uid
返回代表当前运行程序的用户的 uid_t
值,而 get_user_by_uid
函数扫描用户数据库并返回包含用户信息的 User
。当不存在该 ID 的用户时,此函数返回 None
。
User
有以下访问器
- uid: 用户的ID
- name: 用户的名称
- primary_group: 该用户主要组的ID
这是一个完整的示例,用于打印当前用户名。
use users::{get_user_by_uid, get_current_uid};
let user = get_user_by_uid(get_current_uid()).unwrap();
println!("Hello, {}!", user.name());
此代码假设(使用 unwrap()
)在程序开始运行后用户未被删除。对于任意的用户ID,这 不是 一个安全的假设:在程序运行时可能删除用户,或者用户是文件的所有者,或者该用户可能从未存在过。因此,总是要检查返回值!
还有一个名为 get_current_username
的函数,因为这是一个非常常见的操作,所以值得特殊处理。
缓存
尽管有上述警告,用户和组数据库很少改变。虽然短程序可能只需要获取一次用户信息,但长时间运行的程序可能需要多次重新查询数据库,而中等长度的程序可以通过缓存值来减少冗余的系统调用。
因此,此crate为数据库提供了一个缓存接口,该接口在保持每个结果的同时提供相同的功能,并将信息缓存起来以便重新使用。
要引入缓存,创建一个新的 UsersCache
并在它上面调用相同的方法。例如
use users::{Users, Groups, UsersCache};
let mut cache = UsersCache::new();
let uid = cache.get_current_uid();
let user = cache.get_user_by_uid(uid).unwrap();
println!("Hello again, {}!", user.name());
此缓存是 只增的:无法删除它,或删除选定的条目,因为当数据库可能已被修改时,最好是完全重新开始。所以为了实现这一点,只需开始使用一个新的 UsersCache
。
组
最后,可以通过类似的方式获取组。一个 Group
具有以下访问器
- gid: 组的ID
- name: 组的名称
并且,再次提供一个完整的示例
use users::{Users, Groups, UsersCache};
let mut cache = UsersCache::new();
let group = cache.get_group_by_name("admin").expect("No such group 'admin'!");
println!("The '{}' group has the ID {}", group.name(), group.gid());
日志记录
默认启用的 logging
功能使用 log
crate 以 Trace 日志级别记录与操作系统的所有交互。
注意事项
你应该准备应对用户和组表可能完全损坏:不应假设ID映射到实际用户和组,并且用户名和组名也不保证映射!
可模拟的用户和组
当你测试代码时,你不想实际依赖于系统实际存在各种用户和组 - 有一个自定义的用户集会更好,这样可以保证它们存在,以便你可以针对它们进行测试。
《code>mock 模块允许你创建这些自定义用户和组定义,然后使用与主库中相同的 Users
trait 访问它们,而对代码的更改很少。
创建模拟用户
模拟用户表需要预先了解当前用户的UID。除了这一点之外,你可以使用 add_user
和 add_group
将用户和组添加到表中
use std::sync::Arc;
use users::mock::{MockUsers, User, Group};
use users::os::unix::{UserExt, GroupExt};
let mut users = MockUsers::with_current_uid(1000);
let bobbins = User::new(1000, "Bobbins", 1000).with_home_dir("/home/bobbins");
users.add_user(bobbins);
users.add_group(Group::new(100, "funkyppl"));
导出的内容重新导出到模拟模块中,以便更简单的 use
语句。
使用模拟用户
为了设置程序以使用任一类型的 Users
表,让你的函数和结构体接受一个实现 Users
trait 的泛型参数。然后,你可以传递 OS 或 Mock 类型的值。
下面是一个完整的示例
use std::sync::Arc;
use users::{Users, UsersCache, User};
use users::os::unix::UserExt;
use users::mock::MockUsers;
fn print_current_username<U: Users>(users: &mut U) {
println!("Current user: {:?}", users.get_current_username());
}
let mut users = MockUsers::with_current_uid(1001);
users.add_user(User::new(1001, "fred", 101));
print_current_username(&mut users);
let mut actual_users = UsersCache::new();
print_current_username(&mut actual_users);
依赖关系
~64KB