Как безопасно выйти рано из скрипта bash?

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

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

Ответы, подобные этому, кажутся основанными наexitmsgstr ", но если скрипт получен, то есть запускается с".префикс (точка), скрипт выполняется в контексте текущей оболочки, в этом случае 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 ответ

Решение

Наиболее распространенным решением для выхода из сценария без прерывания работы родительской оболочки является попытка 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}",

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

Другие вопросы по тегам