Определение состояния выхода при замене процесса - PullRequest
0 голосов
/ 19 февраля 2019

В настоящее время я использую bash 4.1 и использую функцию для выполнения SVN-кошки в файле репозитория.После этого он выполняет итерацию по каждой строке для выполнения некоторых преобразований (в основном, конкатенации и тому подобное).Если указанный файл не существует, сценарий должен остановиться с сообщением об ошибке.Сценарий выглядит следующим образом:

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 не удался и должен полностью остановить скрипт?

Невозможно использовать опцию set -e, поскольку мне требуется удалить некоторые файлы, созданные в процессе.

Обновление : Я пытался добавить ||завершить работу после команды done следующим образом:

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

Однако скрипт ожидает вывода пользователя, и когда я нажимаю клавишу ввода, он выполняет содержимое цикла while

1 Ответ

0 голосов
/ 19 февраля 2019

Отслеживание состояния выхода из подстановки процесса довольно сложно и требует очень современной версии bash (на мой взгляд, я хочу сказать, 4.3 или новее).До этого $! после <(getFile) не будет заполняться правильно, и поэтому wait не будет работать (или, что еще хуже, относится к ранее запущенному подпроцессу).

#!/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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...