Размонтировать: цель занята в переменную

typeset- этоprivate(ksh93, использующий статическую область видимости, такую ​​как perlmy, а не local, которая выполняет динамическую область видимости )только для функций, которые объявлены с использованием стиля определения функции ksh:

function foo {
  typeset var=whatever
 ...
}

С синтаксисом Bourne (или с командой .(, которая, кстати, также может использоваться в функциях стиля ksh -)), нет области видимости (, за исключением $1, $2... $#конечно ). Таким образом, можно использовать функции стиля Bourne -для получения значения или изменения значения или типа переменной в родительском контексте (, хотя typeset -nтакже можно использовать для этого со стилем ksh -.

В ksh88 typesetвыполнял динамическую область видимости как со стилем определения функции ksh, так и со стилем определения функции Борна. По словам Дэвида Корна, POSIX не определял область видимости переменных ksh на том основании, что она была динамической(признанной низшей ), поэтому он изменил ее на статическую область видимости дляksh93(полной перезаписи ).

Но тем временем другие оболочки реализовали переменную область видимости, и все они использовали динамическую область видимости для имитации ksh88.

zshтеперь имеет ключевое слово privateдля области видимости, аналогичной ksh93, в дополнение к local/ typesetс динамической областью видимости, как в ksh88.

Чтобы увидеть разницу между статической и динамической областью видимости, сравните:

"$shell" -c 'function f { typeset a=1; g; echo "$a"; }
             function g { echo "$a"; a=2; }
             a=0; f'

Который с $shell== ksh93выводит:

0
1

И с выходами ksh88или bash:

1
2

zsh:

$ zsh -c 'zmodload zsh/param/private
          f() { private a=1; g; echo $a;}
          g() { echo $a; a=2; }
          a=0; f'
0
1

Чтобы иметь возможность использовать локальную область видимости в коде, переносимом на bash, zsh, ksh88ksh93, pdksh, yashили dash/FreeBSDsh, вы можете сделать:

[ -n "$BASH_VERSION" ] && shopt -s expand_aliases
alias shdef= kshdef='#'
if type typeset > /dev/null 2>&1; then
  alias mylocal=typeset
  if (a=1; f() { typeset a=2; }; f; [ "$a" = 2 ]); then
    alias shdef='#' kshdef='function'
  fi
else
  alias mylocal=local
fi

А затем объявите свои функции как:

kshdef foo
shdef foo()
{
  mylocal var
  var=value
 ...
}

В любом случае существует много различий между поведением тех localв различных оболочках.Помимо упомянутого выше динамического и статического соображений, существует вопрос о том, получают ли переменные изначально неустановленное или пустое значение или наследуют значение из родительской области. И есть взаимодействие с readonly, unset, независимо от того, является ли local/ typesetключевым словом или встроенным (, влияет на обработку split+glob )...

Существуют и другие последствия использования определения функции стиля ksh -в ksh93, подробности см. на справочной странице.

Подробнее

0
06.09.2019, 03:41
1 ответ

Программы обычно записывают сообщения об ошибках в поток ввода-вывода «стандартная ошибка»; «stderr» для краткости. Если вы будете искать этот термин, вы получите миллионы результатов; короткое объяснение заключается в том, что существует stderr, поэтому сообщения об ошибках могут и будут перейти на экран при перенаправлении «стандартный вывод» («stdout» ), как в гипотетической команде типа

umount /dev/sdb1 > um.result.txt

И вы можете видеть, как это происходит; сообщение об ошибке появляется на вашем экране даже если вы пытаетесь зафиксировать его в переменной.

Такой же короткий ответ – использовать 2>&1чтобы объединить поток stderr с потоком stdout, поэтому

foo=$(umount /dev/sdb1 2>&1)

зафиксирует сообщение об ошибке в переменной.

Другой подход, , предложенный jordanm в комментарии , это посмотреть статус выхода. Вариации на эту тему включают :

umount /dev/sdb1  ||  complain to user
if ! umount /dev/sdb1
then
    complain to user
fi
umount /dev/sdb1 2> /dev/null  ||  complain to user
 foo=$(umount /dev/sdb1 2>&1)  ||  complain to user using "$foo"
3
28.01.2020, 02:22

Теги

Похожие вопросы