.NET 6 當 ProcessStartInfo username無法在 Linux 上使用
最近在移植 CSharp .NET Framework 到 .NET 6 並且在 Linux 上呼叫批次程式時,遇到一個難題那就是沒辦法更換身分。要如何讓.NET在Linux 上轉換身分執行程式,這時候就只能改寫既有程式,以符合Linux規則。
程式範例如下
- RedirectStandardInput 一定要設為 true,我們要模擬使用者逐一輸入指令
- 程式為 /bin/bash
- 轉換身分後逐一輸入指令
using System;
using System.Diagnostics;
namespace SuUserAndReloadProfile
{
class Program
{
static void Main(string[] args)
{
string targetUser = "other_user"; // Replace this with the target user's username.
string targetUserPassword = "password"; // Replace this with the target user's password.
// Create the process start info.
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
// Start the process.
Process process = new Process { StartInfo = processStartInfo };
process.Start();
// Execute the commands as the target user.
process.StandardInput.WriteLine($"echo {targetUserPassword} | su - {targetUser}"); // Run command as the target user.
process.StandardInput.WriteLine("source ~/.profile"); // Reload the profile.
process.StandardInput.WriteLine("whoami"); // Print the current user's name.
process.StandardInput.WriteLine("exit"); // Exit the su session.
// Read the output.
string output = process.StandardOutput.ReadToEnd();
string errorOutput = process.StandardError.ReadToEnd();
// Wait for the process to exit.
process.WaitForExit();
// Display the output and error output (if any).
Console.WriteLine("Output:");
Console.WriteLine(output);
if (!string.IsNullOrEmpty(errorOutput))
{
Console.WriteLine("Error Output:");
Console.WriteLine(errorOutput);
}
// Close the process.
process.Close();
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
同場加映
Async Task 中執行 Thread
使用Async加上Thread,使得程式可同時擁有兩種特性的好處。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncTaskWithThreadExample
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Main thread: Starting the async operation...");
// Start the async operation.
await AsyncTaskWithThread();
Console.WriteLine("Main thread: Async operation completed.");
Console.ReadKey();
}
private static async Task AsyncTaskWithThread()
{
Console.WriteLine("AsyncTaskWithThread: Starting the task...");
// Start a new thread using Task.Run().
var task = Task.Run(() => ThreadOperation());
// Wait for the thread to complete.
await task;
Console.WriteLine("AsyncTaskWithThread: Task completed.");
}
private static void ThreadOperation()
{
Console.WriteLine("ThreadOperation: Executing on a separate thread.");
// Simulate some work.
Thread.Sleep(2000);
Console.WriteLine("ThreadOperation: Work completed on the separate thread.");
}
}
}
取得 Async 執行結果
要獲得async task的結果,您可以在C#中使用await關鍵字。 await關鍵字與返回Task
using System;
using System.Threading.Tasks;
namespace GetAsyncTaskResultExample
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Main thread: Starting the async operation...");
// Call the async method and get the result.
int result = await GetResultAsync();
Console.WriteLine($"Main thread: Async operation completed with result: {result}");
Console.ReadKey();
}
private static async Task<int> GetResultAsync()
{
Console.WriteLine("GetResultAsync: Starting the task...");
// Simulate some work by delaying the task.
await Task.Delay(2000);
// Set a result value.
int result = 42;
Console.WriteLine("GetResultAsync: Task completed.");
// Return the result.
return result;
}
}
}