簡體   English   中英

如何在 macOS 上運行 Bash 腳本並異步接收其退出代碼?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM