- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要在 Linux 机器上对服务安装程序进行一些简单的文件操作。代码为 .NET 5.0。
我当前的版本使用 Process.Start()
来执行 shell 命令来更改文件和目录的所有者并设置权限。
这非常慢(我使用异步方法),尤其是与 Windows 等效方法相比。
我看到可从 .NET 调用的 libc
有方法 chmod
和 chown
,但是它需要 uid
和 gid
参数。我的应用程序不知道这些 ID,至少在不使用 shell 的情况下是这样。
到目前为止,我得到的是这样的:
const string LIBC = "libc";
[DllImport(LIBC, SetLastError = true)]
private static extern int chmod(string path, uint mode);
[DllImport(LIBC, SetLastError = true)]
private static extern int chown(string path, int owner, int group);
那么...如何获得所需的这 2 个整数?
更新
为什么有人认为这个问题(尤其是考虑到它的标题)是关于相似但不同事物的问题的重复。
我知道如何通过多种方式更改 Linux 文件的所有者和权限。最简单的方法是使用 Linux shell。最快最简单的方法是使用内部调用 libc
的 Mono.Posix.NETStandard
库。
我的具体问题是它是如何制作的?它是如何工作的?
更具体地说:这是 getpwnam()
的 Linux 手册页: https://man7.org/linux/man-pages/man3/getpwnam.3.html
如何使用 p/invoke 从 C# 调用它?我在许多示例中看到,当他们将 char*
替换为 string
时,它会以某种方式神奇地起作用。我创建了一个这样的结构:
public struct PASSWD {
public string pw_name; /* username */
public string pw_passwd; /* user password */
public int pw_uid; /* user ID */
public int pw_gid; /* group ID */
public string pw_gecos; /* user information */
public string pw_dir; /* home directory */
public string pw_shell; /* shell program */
};
...并尝试将其用作签名的 out
参数。我没有收到任何错误,但它就是行不通。我得到的结构是空的。
所以,我们再次使用平台调用,在 C# 中,我们正在调用 libc
并且我们希望从结构中获取结果。据我谷歌搜索 - 它不是谷歌可用的。只有 Mono
源代码,它使用实现我需要的外部模块。我怀疑他们这样做是出于性能原因,也使用了一些特殊工具,因为在评论中表示代码已生成。
我的问题又是,如何使用 Linux 手册页定义为 C# 创建适当的方法签名,以便能够从 getpwnam()
中提取这 2 个整数。
我也很好奇 .NET 本身是否已经存在类似的东西,但我想它不存在。
最佳答案
因此,我对 p/invoke 感到生疏。我的问题是我忘记了,当 native 函数返回一个指向结构的指针时,没有自动转换,我必须在签名中留下指针,所以:
[DllImport(LIBC, SetLastError = true)]
internal static extern IntPtr getgrnam(string name);
[DllImport(LIBC, SetLastError = true)]
internal static extern IntPtr getpwnam(string name);
internal struct Group {
public string Name;
public string Password;
public uint Gid;
public IntPtr Members;
}
internal struct Passwd {
public string Name;
public string Password;
public uint Uid;
public uint Gid;
public string GECOS;
public string Directory;
public string Shell;
}
让我们创建完全托管的 .NET 样式类型:
public sealed class GroupInfo {
public string Name { get; }
public uint Id { get; }
public string[] Members { get; }
internal GroupInfo(Syscall.Group group) {
Name = group.Name;
Id = group.Gid;
Members = GetMembers(group.Members).ToArray();
}
private static IEnumerable<string> GetMembers(IntPtr members) {
IntPtr p;
for (int i = 0; (p = Marshal.ReadIntPtr(members, i * IntPtr.Size)) != IntPtr.Zero; i++)
yield return Marshal.PtrToStringAnsi(p)!;
}
}
public class UserInfo {
public string Name { get; }
public uint Uid { get; }
public uint Gid { get; }
public string? Directory { get; }
public string? Shell { get; }
internal UserInfo(Syscall.Passwd passwd) {
Name = passwd.Name;
Uid = passwd.Uid;
Gid = passwd.Gid;
Directory = passwd.Directory;
Shell = passwd.Shell;
}
}
它可以这样使用:
public static UserInfo? GetUserInfo(string name) {
var result = Syscall.getpwnam(name);
if (result != IntPtr.Zero) return new UserInfo(Marshal.PtrToStructure<Syscall.Passwd>(result));
return null;
}
public static GroupInfo? GetGroupInfo(string name) {
var result = Syscall.getgrnam(name);
if (result != IntPtr.Zero) return new GroupInfo(Marshal.PtrToStructure<Syscall.Group>(result));
return null;
}
关于c# - 如何使用 p/invoke 在 Linux 上获取 UID 和 GID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69750698/
我可能没有在此处查询中的最佳查询,如果有人可以教我更好的方法,我将不胜感激。 但是根据我所拥有的,我似乎无法弄清楚为什么 LIMIT 命令不起作用? 我将缩略图限制为 26 个,但我得到了 38 个?
我正在尝试在 red hat vm 上使用 yum 安装 logstash,我已经根据指南设置了 logstash.repo 文件并运行了 yum 安装 logstash 但是我在下载所有内容后出现以
Closed. This question needs debugging details。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。 24天前关闭。
这是我们生产环境中的一个问题。我们使用Kubernetes通过Pods部署我们的应用程序。 Pod可能需要一些存储空间来存储文件。 我们使用“Persistent Volume”和“Persisten
我需要为 Linux 实现一个类似于计划 9 的小型功能系统 cap设备。主机所有者(Linux 中的 root)允许 user1 模拟 user2 将 user1@user2@random-stri
我想打印要打印的特定用户的 GID 和 UID,例如用户是学生,我希望仅使用 Linux 终端为他们打印 GID 和 UID 最佳答案 他们说的是真的,但为了帮助您:查看 id 命令。 关于linux
我需要更改我的父进程的 PGID,所以我做了这样的事情: #include #include #include #include #define KIDS 10 int main() {
假设我有一个大小为 100 的纹理宽度和 100高度并将其分派(dispatch)到 {10, 10, 1} 中的内核函数线程组和大小。 我无法理解 thread_position_in_grid从
我正在尝试将用户图片保存到 Firebase Storage,检索其 downloadUrl 并将其全部保存到 CoreData。我调用上传函数,并在完成后调用 CoreData 保存函数。除了一个小
在服务器方面,我完全是个菜鸟。我正在尝试登录 WHM,但出现此错误: “内部服务器错误” 500 无法为 root 获取 uid 或 gid” 我现在的问题是,什么是“gid”?我想象“uid”是“U
我的应用程序创建了一个基本的 ACL,并将其传递给内核模块。 ACL 包含一个 UID/GID 列表。对这些 ID 的检查是自定义的,并且在系统已经提供的内容之上。 现在,如果根/用户更改 UID/G
我自己的问题的长答案是通过谷歌搜索但没有找到任何有用的东西,就是筛选“ps”的来源。但在我这样做之前,有没有人愿意提供懒人的解决方案? :-) 我发现了这个问题:Knowing the process
命 令:id 功能说明:查看显示目前登陆账户的uid和gid及所属分组及用户名 语 法:id [-gGnru][--help][--version][用户名称] 补充说明:id会显示用户以及
我正在尝试禁用除“neta”组成员之外的所有用户对 IP 1.2.3.4 的访问。这是我专门为此创建的一个新组。 iptables -I OUTPUT -o eth0 -p tcp -d 1.2.3.
我在磁盘上有一个目录,归 share 所有gid 为 1001 .我想将该目录添加为其中一个 lxc 容器上的设备,并让该组结转。 我试过使用 raw.idmap 'gid 1001 1001'但是如
最近我正在使用 Phaser.js 开发一个游戏,我开始需要我的瓦片 map 对象,我来看看这个 video . 唯一的问题是看到这个的“ Sprite 制造对象”example ,这个方法用到了ma
我已经阅读了谷歌文档来寻求答案,我也查看了一些类似的帖子,但这些都没有帮助我解决我的问题。我正在尝试将 UIButton 设置为 google 登录的触发器。由于某种原因,它压碎了。我当然会添加我编写
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我对 Linux 很陌生,所以我知道这个问题很愚蠢。对不起。 我检查了用户和组,有些用户的 uid 和 gid 不同,所以我只是想让它们同步。 tail -6 /etc/passwd mysql:x:
如果我的 Java 类中有一个属性“gId”,访问器方法应该命名为什么? getGId 是我假设的。 如果有一个属性 gURL 我想它会是 getGURL,它看起来有点丑(尽管不是指 girl 的替代
我是一名优秀的程序员,十分优秀!