[英]How to run a Bash script and receive its exit code asynchronously on a macOS?
我是 macOS 開發人員的新手。 我的大部分背景都在 Windows 上。
我正在嘗試為我的啟動守護程序編寫一個 function,它應該通過它的文件路徑運行一個 Bash 腳本,然后在它完成運行時得到異步通知並獲取它的退出代碼(我認為它在 Linux 上被稱為“狀態代碼”。)或者發送如果無法運行 Bash 腳本,則回調中出現錯誤。
我正在使用以下內容,其中還包括我在評論中的兩部分問題:
void RunExternalScript(const char* pScriptFilePath,
void (*pfnCallback)(int exitCode, const void* pParam),
const void* pParam)
{
//'pfnCallback' = should be called when 'pScriptFilePath' finishes running
//Fork our process
pid_t pidChild = fork();
if(pidChild == 0)
{
//Child process, start our Bash script
execl(pScriptFilePath, (const char*)nullptr);
//We get here only if we failed to run our script
log("Error %d running script: %s", errno, pScriptFilePath);
abort();
}
else if(pidChild != -1)
{
//Started our script OK, but how do I wait for it
//asynchronously to finish?
//
//If I call here:
//
// int nExitCode;
// waitpid(pidChild, &nExitCode, 0);
//
//It will block until the child process exits,
//which I don't want to do since I may want to
//run more than one script, plus my daemon may
//receive a request to quit, so I need to be able
//to cancel this wait for the child process...
//And the second question:
//
//How do I know from this process that the forked
//process failed to run my script?
}
else
{
log("Error running: %s", pScriptFilePath);
}
}
您可以使用帶有“WNOHANG”選項的“waitpid”function。 這將允許您等待子進程完成,但不會阻止調用進程。 然后您還可以檢查“waitpid”的返回值以確定子進程是否已完成。
要檢查子進程是否運行腳本失敗,可以檢查“execl”的返回值。
void RunExternalScript(const char* pScriptFilePath,
void (pfnCallback)(int exitCode, const void pParam),
const void* pParam)
{
pid_t pidChild = fork();
if(pidChild == 0)
{
if (execl(pScriptFilePath, (const char*)nullptr) == -1)
{
log("Error %d running script: %s", errno, pScriptFilePath);
exit(EXIT_FAILURE);
}
}
else if(pidChild != -1)
{
int nExitCode;
pid_t ret = waitpid(pidChild, &nExitCode, WNOHANG);
if (ret == -1)
{
log("Error %d waiting for child process", errno);
}
else if (ret == 0)
{
}
else
{
if (WIFEXITED(nExitCode))
{
nExitCode = WEXITSTATUS(nExitCode);
}
else
{
nExitCode = -1;
}
pfnCallback(nExitCode, pParam);
}
}
else
{
log("Error running: %s", pScriptFilePath);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.