Локальные переменные в bash:локальный против подоболочки

StackOverflow https://stackoverflow.com/questions/4625309

Вопрос

Насколько я знаю, существует два способа создания локальных переменных в функции bash:создайте подоболочку или объявите каждую переменную локальной.

Например:

# using local
function foo
{
  local count
  for count in $(seq 10)
  do
    echo $count
  done
}

или

# using subshell
function foo
{
  (
    for count in $(seq 10)
    do
      echo $count
    done
  )
}

Очевидно, что версию, использующую подоболочку, проще написать, потому что вам не нужно заботиться об объявлении всех локальных переменных (не говоря уже о переменных (среды), созданных/экспортируемых такими инструментами, как получить).Но я мог себе представить, что создание подоболочки требует дополнительных затрат.

Так какой же подход лучше?Каковы плюсы/минусы?

Это было полезно?

Решение

Создание подоболочки включает в себя fork(), поэтому у него определенно есть накладные расходы по сравнению с локальной переменной.Хотя субоболочки дешевы (вы не беспокоитесь об их стоимости, когда они вам нужны), они не бесплатны.

Если ваш скрипт будет интенсивно использоваться и производительность действительно имеет значение (поэтому сотни пользователей будут запускать его одновременно, много раз в день), тогда вы можете беспокоиться о стоимости производительности подоболочки.OTOH, если вы запускаете его раз в месяц, а сценарий в целом выполняется менее 10 секунд, вы, вероятно, этого не сделаете.

Однако с точки зрения ясности гораздо лучше быть явным и объявить переменные — это снижает риск поломки скрипта, потому что кто-то придет и скажет: «Эта подоболочка явно не нужна» (и это действительно не нужно). т;Я бы хотел удалить подоболочки из ваших функций).

Посмотрите на эволюцию сценариев Perl.Они начинались как всеобщие переменные, возникающие по требованию.Постепенно они стали более строгими, и теперь обычным стилем является предварительное объявление всех переменных.В какой-то степени оболочки пошли по тому же пути, но не так строго, как Perl.Awk также представляет собой интересный пример;его функции используют глобальные переменные, если только они не являются аргументами функции, что приводит к написанию функций с 3 активными аргументами (скажем) и 5 ​​неактивными аргументами, которые эффективно определяют локальные переменные.Это немного эксцентрично, хотя и «работает».

Другие советы

Теперь, убедившись, что все функции всегда объявляют все переменные как местные, довольно сложно.

Я думаю, что это очень распространено и предпочитает всегда использовать функции подпунктов:

f() (
 echo "we are a subshell"
)

Нет необходимости объявлять локальные переменные - но и никакой способ изменить глобальные переменные. Что хорошо, на мой взгляд!

Одним из дополнительных последствий, что вам всегда нужно проверить код возврата / выхода из таких функций и действовать соответственно! Это, потому что вы не можете выйти из вас скрипт из функции подпунктов!

f() (
   echo "Trying to exit"
   exit 1
)

f
echo "Did not exit"

Это не выйдет на ваш скрипт. Вы должны сделать это таким образом:

f() (
   echo "Trying to exit"
   exit 1
)

f || exit $?
echo "Did not exit"

Это выйдет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top