Я могу определить bash
функции, используя или опуская function
ключевое слово. Есть ли разница?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Оба вызова функций foo
и bar
успешно, и я не вижу никакой разницы. Поэтому мне интересно, если это просто для улучшения читабельности, или есть что-то, что мне не хватает ...
Кстати, в других оболочках, таких как dash
( /bin/sh
обозначается dash
в debian / ubuntu), происходит сбой при использовании function
ключевого слова.
function baz { echo "baz"; }
. Смотрите Bashism в вики GreyCat.Ответы:
Там нет никакой разницы AFAIK, кроме того, что вторая версия является более портативной.
источник
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
не предупредив его, сначала перепроверить, может ли версия tar на desthost избавиться от "/", может привести к бедствия в некоторых случаях ...). Например: если вы используете afunction tar { #a safe tar with safety checks ... }
иsh
игнорируете его, ...sh
распознаваниеfunction
ключевого слова, и, в общем, предполагающие общие, но нестандартные функции, которые оболочка любитksh
иbash
предлагает, также часто не будут работать в более новых производственных системах, даже если они работали в более старых выпусках та же ОС.bash
до сих пор используетсяsh
во многих системах GNU / Linux, но некоторые популярные дистрибутивы перешли наsh
использование символической ссылки наdash
(оболочка Debian Almquist) для повышения производительности. Это включает в себя Debian и Ubuntu .function
Ключевое слово было введено в KSH . Традиционная оболочка Bourne имела толькоfoo ()
синтаксис, а POSIX стандартизирует толькоfoo ()
синтаксис.В ATT ksh (но не в pdksh) есть несколько различий между функциями, определенными с помощью,
function
и функциями, определенными с помощью синтаксиса Bourne / POSIX. В функциях , определяемыхfunction
, тоtypeset
ключевое слово объявляет локальную переменную: один раз при выходе из функции, значение переменной сбрасывается на то , что это было перед входом в функцию. С классическим синтаксисом переменные имеют глобальную область видимости независимо от того, используете вы ееtypeset
или нет.Другое отличие в ksh состоит в том, что функции, определенные с помощью
function
ключевого слова, имеют свой собственный контекст прерывания. При выполнении функции ловушки, определенные вне функции, игнорируются, а фатальные ошибки внутри функции выходят только из функции, а не из всего сценария. Кроме того,$0
это имя функции в функции, определенной как,function
но имя скрипта в функции, определенной с()
.Пдкш не эмулирует ATT кш. В pdksh
typeset
создает переменные локальной области видимости независимо от функции, и локальных ловушек нет (хотя использованиеfunction
имеет некоторые незначительные отличия - подробности см. На странице man).Bash и zsh представили
function
ключевое слово для совместимости с ksh. Однако в этих оболочкахfunction foo { … }
иfoo () { … }
строго идентичны, как Баш и ЗШ расширениеfunction foo () { … }
.typeset
Ключевое слово всегда объявляет локальные переменные ( за исключением-g
, конечно), и ловушки не являются локальными (вы можете получить локальные ловушки в Zsh, установивlocal_traps
опцию).источник
foo() command
синтаксис, а синтаксис Bourne позже был добавлен в оболочку Korn для совместимости.function { ... }; f;
пропускаетf
послеfunction
ключевого слова?Синтаксис Борна поддерживается любой Борн-подобной оболочкой , но
bash
,yash
и последние версииposh
(которые поддерживают только составные команды). (оболочки Bourne и реализации AT & Tksh
не поддерживают,foo() any-command > redirections
если толькоany-command
это не составная команда).(примеры соединения команд:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... наиболее часто используемый существо{ ...; }
)является синтаксисом POSIX, поддерживаемым любой подобной Bourne оболочкой, и той, которую вы обычно хотите использовать.
синтаксис оболочки Korn, предшествующий синтаксису Борна. Используйте его, только если вы пишете специально для AT & T-реализации оболочки Korn и нуждаетесь в особой обработке, которую он там получает. Этот синтаксис не POSIX, но поддерживается
bash
,yash
иzsh
для совместимости с оболочкой Korn , хотя эти снаряды (иpdksh
-А варианта Korn оболочки) не относиться к нему не отличаются от стандартного синтаксиса.это синтаксис без оболочки и не должен использоваться . Это происходит только при поддержке аварии на
bash
,yash
,zsh
и наpdksh
основе вариантов оболочки Korn. Кстати, это такжеawk
синтаксис функции.Если мы продолжим идти по эзотерическому списку,
(вроде
function foo() (subshell)
илиfunction foo() for i do; ... done
) еще хуже. Она поддерживаетсяbash
,yash
иzsh
, но не КШ, дажеpdksh
-На варианты.Пока:
поддерживается только
zsh
.источник
function
ключевое слово, так и скобки, задокументирован в Bash. В руководстве по Bash 4.2 и более поздним версиям говорится, что функции объявляются синтаксисомname () compound-command [ redirections ]
илиfunction name [()] compound-command [ redirections ]
. В Bash 4.1.11 вплоть до версии 3.0-бета, которая была просто одной строкой,[ function ] name () compound-command [redirection]
которая ошибочно не охватывает синтаксис, включающийfunction
ключевое слово, но не содержит скобки, но все же охватывает синтаксис, который включает какfunction
ключевое слово, так и скобки.bash
распознаетfunction foo {
в дополнение кfoo() {
совместимости с оболочкой Korn (и всегда имеет), чтобы он мог интерпретировать сценарии, написанные для оболочки Korn. Он также поддерживаетfunction foo () {
, но нет веских причин использовать его.function f() {
. А именно, с точки зрения читабельности, она будет распознаваться как функция всеми, кто знает английский и всеми, кто знает C, по сравнению только с одним из этих наборов.You should never combine the keyword function with the parentheses () when defining a function.
Семантически эти две формы эквивалентны в Bash.
Со страницы руководства:
РЕДАКТИРОВАТЬ: я только заметил, что этот вопрос помечен
posix
. В POSIXsh
, тоfunction
ключевое слово не используется (хотя он зарезервирован).источник
Несколько других уже ответили правильно, но вот мой краткий обзор:
Вторая версия является переносимой и, вероятно, будет работать со многими стандартными (особенно POSIX) оболочками.
Первая версия будет работать только с bash, но вы можете опустить скобки после имени функции вместе с ним.
В противном случае они представляют идентичные сущности после того, как bash их интерпретирует.
источник
()
иfunction
ключевое слово оболочка ведет себя так , как будто вы только что сделали вfoo(){ ...; }
любом случае, за исключением, конечно, для оболочки , в которой он является недействительным синтаксис. и так вы должны делать,function foo { ...; }
если нужно, илиfoo(){ ...; }
иначе.