C# - 특정 실행 파일이 있는지 확인하는 방법 (Linux)
윈도우와는 달리, 리눅스의 경우 배포본도 다양하지만 컨테이너 환경으로 오면서 더더욱 간소화된 이미지까지 겹쳐 당연히 있을 것 같은 파일들이 없는 경우가 많습니다.
혹시 이런 경우, 뭔가 해당 파일의 유무를 판단할 만한 좋은 근거가 있을까요? ^^; 제가 리알못이라... 가령 systemctl이 있다고 가정했을 때 Ubuntu 20.04에서는 /usr/bin/systemctl에 위치하고 있으므로 이 경로에 대한 판정을 하면 될 것 같은데, 아니면 다른 위치에도 설치되는 경우가 있는 지도 잘 모르겠습니다. (혹시 아시는 분은 덧글 부탁드립니다. ^^)
만약 다양한 경로에 있는 것이 가능하다면, 실행 파일의 유무를 단순하게 다음과 같이 실행해 보고 예외 체크를 하는 식으로 접근할 수 있습니다.
static void Main(string[] args)
{
Console.WriteLine(HasExecutable("systemctl")); // True
Console.WriteLine(HasExecutable("systemctl2")); // False
}
static bool HasExecutable(string executable)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = executable;
psi.RedirectStandardOutput = true;
try
{
using (Process? process = Process.Start(psi))
{
return true;
}
}
catch { }
return false;
}
단지 기분나쁜 점이 있다면 디버깅 시에 예외가 하나 발생한다는 정도인데요,
Exception thrown: 'System.ComponentModel.Win32Exception' in System.Diagnostics.Process.dll
이를 우회하고 싶다면 which를 이용하는 것도 괜찮을 것 같습니다.
static bool HasExecutable(string executable)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "which";
psi.Arguments = executable;
psi.RedirectStandardOutput = true;
using (Process? process = Process.Start(psi))
{
if (process == null)
{
return false;
}
process.WaitForExit();
return process.ExitCode == 0;
}
}
하지만 이것도 단점이 있을 듯한데요, 어쩌면 어느 컨테이너인가는 which가 없을 수도 있기 때문입니다. 그렇다면 저 2가지 방법을 혼합하는 것이 그나마 가장 나은 선택일 것 같습니다.
using System.Diagnostics;
namespace ConsoleApp1;
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(HasExecutable("systemctl"));
Console.WriteLine(HasExecutable("systemctl2"));
}
#if DEBUG
static bool HasExecutable(string executable)
{
// ...[생략: which를 이용한 체크]...
}
#else
static bool HasExecutable(string executable)
{
// ...[생략: 곧바로 실행]...
}
#endif
}
아니면, 윈도우처럼 Path 환경변수를 돌면서 실행 파일이 있는지 검색하는 것도 좋을 듯하고. (혹시 좀 더 괜찮은 방법을 알고 계신 분이 있다면 덧글 부탁드립니다. ^^)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]