Как безопасно выйти рано из скрипта bash? - PullRequest
0 голосов
/ 25 августа 2018

Я знаю, что есть несколько вопросов SO по exit против return в bash сценариях (например, здесь ).

По этой теме, но отличается от существующих вопросовЯ полагаю, я хотел бы знать, существует ли «наилучшая практика» для безопасной реализации «раннего возврата» из сценария bash, чтобы текущая оболочка пользователя не закрывалась, если они исходят из сценария.

Ответы, такие как this , кажутся основанными на "exit", но если сценарий получен, то есть выполняется с префиксом "." (точка), сценарий выполняется в контекст текущей оболочки , в этом случае оператор exit имеет эффект выхода из текущей оболочки.Я предполагаю, что это нежелательный результат, потому что скрипт не знает, был ли он получен или запущен в подоболочке - если первый, пользователь может неожиданно исчезнуть из своей оболочки.Есть ли способ / лучшие практики для раннего возврата, чтобы не выходить из текущей оболочки, если вызывающая сторона получает ее?

Например, этот сценарий ...

#! /usr/bin/bash
# f.sh

func()
{
  return 42
}

func
retVal=$?
if [ "${retVal}" -ne 0 ]; then
  exit "${retVal}"
#  return ${retVal} # Can't do this; I get a "./f.sh: line 13: return: can only `return' from a function or sourced script"
fi

echo "don't wanna reach here"

... работает без убийствамоя текущая оболочка, если она запускается из подоболочки ...

> ./f.sh 
> 

... но убивает мою текущую оболочку, если она получена:

> . ./f.sh 

Одна идея, которая приходит на умзаключается в том, чтобы вкладывать код в coditionals, чтобы не было явного оператора exit, но мой уклон C / C++ заставляет думать о ранних возвратах как эстетически предпочтительном по сравнению с вложенным кодом.Существуют ли другие решения, которые действительно «с ранним возвращением»?

1 Ответ

0 голосов
/ 25 августа 2018

Наиболее распространенное решение для выхода из сценария без прерывания работы родительской оболочки - сначала попытаться return. Если это не удается, то exit.

Ваш код будет выглядеть так:

#! /usr/bin/bash
# f.sh

func()
{
  return 42
}

func
retVal=$?
if [ "${retVal}" -ne 0 ]; then
  return ${retVal} 2>/dev/null # this will attempt to return
  exit "${retVal}" # this will get executed if the above failed.
fi

echo "don't wanna reach here"

Вы также можете использовать return ${retVal} 2>/dev/null || exit "${retVal}".

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...