Linux/Unix上的.NET Core文件权限

xriantvc  于 2023-05-08  发布在  .NET
关注(0)|答案(4)|浏览(252)

我正在尝试学习如何在Linux/Unix上使用.NET Core设置文件权限。我已经在这里找到了一个问题,它为我指明了System.IO.FileSystem的方向,但是我似乎找不到任何关于如何使用它的文档。
简而言之,我想从一个只在Linux上运行的.NET Core应用程序中chmod一个文件644,但我不知道如何进行。

ut6juiuv

ut6juiuv1#

目前,.NET Core中没有内置的API。然而,.NET Core团队正在努力使Mono.Posix在.NET Core上可用。这将公开API以在托管代码中执行此类操作。参见https://github.com/dotnet/corefx/issues/15289https://github.com/dotnet/corefx/issues/3186。您可以在这里尝试此API的早期版本:https://www.nuget.org/packages/Mono.Posix.NETStandard/1.0.0-beta1

var unixFileInfo = new Mono.Unix.UnixFileInfo("test.txt");
    // set file permission to 644
    unixFileInfo.FileAccessPermissions =
        FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite
        | FileAccessPermissions.GroupRead
        | FileAccessPermissions.OtherRead;

如果不想使用Mono.Posix,可以通过调用本机代码来实现相同的功能。使用P/Invoke,可以从libc调用chmod函数。有关本机API的更多详细信息,请参阅man 2 chmod

using System;
using System.IO;
using System.Runtime.InteropServices;
using static System.Console;

class Program
{
    [DllImport("libc", SetLastError = true)]
    private static extern int chmod(string pathname, int mode);

    // user permissions
    const int S_IRUSR = 0x100;
    const int S_IWUSR = 0x80;
    const int S_IXUSR = 0x40;

    // group permission
    const int S_IRGRP = 0x20;
    const int S_IWGRP = 0x10;
    const int S_IXGRP = 0x8;

    // other permissions
    const int S_IROTH = 0x4;
    const int S_IWOTH = 0x2;
    const int S_IXOTH = 0x1;

    static void Main(string[] args)
    {
        WriteLine("Setting permissions to 0755 on test.sh");
        const int _0755 =
            S_IRUSR | S_IXUSR | S_IWUSR
            | S_IRGRP | S_IXGRP
            | S_IROTH | S_IXOTH;
        WriteLine("Result = " + chmod(Path.GetFullPath("test.sh"), (int)_0755));

        WriteLine("Setting permissions to 0644 on sample.txt");
        const int _0644 =
            S_IRUSR | S_IWUSR
            | S_IRGRP
            | S_IROTH;
        WriteLine("Result = " + chmod(Path.GetFullPath("sample.txt"), _0644));

        WriteLine("Setting permissions to 0600 on secret.txt");
        const int _0600 = S_IRUSR | S_IWUSR;
        WriteLine("Result = " + chmod(Path.GetFullPath("secret.txt"), _0600));
    }
}
mhd8tkvw

mhd8tkvw2#

我通过启动一个新进程并执行bash chmod命令解决了这个问题。

示例:

public static void Exec(string cmd)
{
    var escapedArgs = cmd.Replace("\"", "\\\"");
        
    using var process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = "/bin/bash",
            Arguments = $"-c \"{escapedArgs}\""
        }
    };

    process.Start();
    process.WaitForExit();
}

然后:

Exec("chmod 644 /path/to/file.txt");

您还可以使用这个Exec方法来运行任何其他类型的bash命令。

polhcujo

polhcujo3#

这里有一个简单的chmod函数,你可以在c#中使用,没有依赖关系。

// Returns true if success and false otherwise
// permissions can be an int or a string. For example it can also be +x, -x etc..
bool Chmod(string filePath, string permissions = "700", bool recursive = false)
{
        string cmd;
        if (recursive)
            cmd = $"chmod -R {permissions} {filePath}";
        else
            cmd = $"chmod {permissions} {filePath}";

        try
        {
            using (Process proc = Process.Start("/bin/bash", $"-c \"{cmd}\""))
            {
                proc.WaitForExit();
                return proc.ExitCode == 0;
            }
        }
        catch
        {
            return false;
        }
}
bksxznpy

bksxznpy4#

我知道这个问题有点老了,但对于.NET 7及以上版本,有一个更简单的API。

File.SetUnixFileMode(path, UnixFileMode.UserRead | UnixFileMode.UserWrite);

相关问题