Linux/C# - 실행 파일이 아닌 스크립트 형식의 명령어를 Process.Start로 실행하는 방법
예를 들어, 리눅스에 .NET Core가 설치되면 하위 폴더에 "createdump"라는 프로그램이 포함됩니다. 그래서 이 프로그램을 (예를 들어, pid == 19234 프로세스에 대해 풀 메모리 덤프를 뜨기 위해) 실행시키려면 다음과 같은 식으로 할 수 있습니다.
$ /usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.7/createdump -u 19234
그런데, 보는 바와 같이 버전도 포함되고 depth도 있어서 일반적인 상황에서 쓰기에는 좀 그렇죠. ^^ 그래서 find 명령을 사용해 이런 부분을 완화할 수 있습니다.
$ $(find /usr/share/dotnet -name createdump) -u 19234
당연히, 이것을
Process.Start로 실행할 수는 없습니다.
string cmd = "$(find /usr/share/dotnet -name createdump) -u 19234";
Process.Start(cmd);
/* 예외 발생
System.ComponentModel.Win32Exception (2): No such file or directory
at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at temp.Program.Main(String[] args) in /home/tusr/temp/Program.cs:line 19
*/
이에 대한 해법은, bash 등의 shell을 경유해 실행시키는 것입니다. 단지, "명령"을 전달하는 경우 "-c" 옵션을 주기 때문에 다음과 같은 식으로 코딩하면 됩니다.
using System;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main(string[] args)
{
string cmd = "$(find /usr/share/dotnet -name createdump) " + Process.GetCurrentProcess().Id;
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false;
psi.FileName = "bash";
psi.Arguments = "-c \"" + cmd + "\"";
try
{
Process child = Process.Start(psi);
child.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
참고로, 아래의 소스 코드가 더 나을 것입니다. ^^
Running shell (bash) commands in .NET Core C#
; https://loune.net/2017/06/running-shell-bash-commands-in-net-core/
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]