检测进程替换的退出状态 [英] Detecting exit status on process substitution

查看:23
本文介绍了检测进程替换的退出状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前使用的是 bash 4.1,我正在使用一个函数在存储库文件上执行 SVN cat.之后,它遍历每一行以执行一些转换(主要是连接等).如果所述文件不存在,脚本应停止并显示错误消息.脚本如下:

I'm currently using bash 4.1 and I'm using a function to perform a SVN cat on a repository file. After that, it iterates over each line to perform some transformations (mostly concatenations and such). If said file does not exist, the script should stop with an error message. The script is as follows:

function getFile {
    svnCat=`svn cat (file) 2>&1` 
    if [[ -n $(echo "$svnCat" | grep "W160013") ]]; then # W160013 is the returned value by SVN stderr case a file doesn't exist
        echo "File doesn't exist" >&2
        exit 1
    else
        echo "$svnCat" | while read -r; do
            #Do your job
        done
    fi
}

function processFile{
    while read -r do
        #do stuff
    done < <(getFile)

    #do even more stuff
}

但是,在文件不存在的情况下,错误信息会打印一次,但脚本会继续执行.有没有办法检测while循环失败并且应该完全停止脚本?

However, in situations where a file does not exist, the error message is printed once but the script keeps executing. Is there a way to detect that the while looped failed and should stop the script completely?

不能使用 set -e 选项,因为我需要删除在此过程中创建的一些文件.

Can't use set -e option since I require to delete some files that were created in the process.

更新:我尝试添加 ||完成命令后退出,如下所示:

Update: I've tried to add || exit after the done command as follows:

function processFile{
    while read -r do
        #do stuff
    done || exit 1 < <(getFile)

然而,脚本正在等待用户输出,当我按下回车键时,它会在 while 循环中执行内容

However, the script is waiting for user output and when I press enter, it executes the content in the while loop

推荐答案

从进程替换中跟踪退出状态很棘手,并且需要非常现代的 bash 版本(我想说 4.3 或更高版本)).在此之前,<(getFile) 之后的 $! 将不会被正确填充,因此 wait 将失败(或者,更糟糕的是,引用一个先前启动的子进程).

Tracking exit status from a process substitution is tricky, and requires a very modern version of bash (off the top of my head, I want to say 4.3 or newer). Prior to that, the $! after the <(getFile) will not be correctly populated, and so the wait will fail (or, worse, refer to a previously-started subprocess).

#!/usr/bin/env bash

### If you *don't* want any transforms at this stage, eliminate getFile entirely
### ...and just use < <(svn cat "$1") in processFile; you can/should rely on svn cat itself
### ...to have a nonzero exit status in the event of *any* failure; if it fails to do so,
### ...file a bug upstream.
getFile() {
    local content
    content=$(svn cat "$1") || exit  # pass through exit status of failed svn cat
    while read -r line; do
      echo "Generating a transformed version of $line"
    done <<<"$content"
}

processFile() {
    local getFileFd getFilePid line

    # start a new process running getFile; record its pid to use to check exit status later
    exec {getFileFd}< <(getFile "$1"); getFilePid=$!

    # actual loop over received content
    while IFS= read -r line; do
      echo "Retrieved line $line from process $getFilePid"
    done <&"$getFileFd"

    # close the FIFO from the subprocess
    exec {getFileFd}<&-

    # then use wait to wait for it to exit and collect its exit status
    if wait "$getFilePid"; then
      echo "OK: getFile reports success" >&2
    else
      getFileRetval=$?
      echo "ERROR: getFile returned exit status $getFileRetval" >&2
    fi
}

这篇关于检测进程替换的退出状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆