Saya dapat mendefinisikan bash
fungsi menggunakan atau menghilangkan function
kata kunci. Apakah ada perbedaan?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Keduanya panggilan ke fungsi foo
dan bar
berhasil dan saya tidak bisa melihat perbedaan. Jadi saya bertanya-tanya apakah itu hanya untuk meningkatkan keterbacaan, atau ada sesuatu yang saya lewatkan ...
BTW di shell lain seperti dash
( /bin/sh
disinkronkan ke dash
dalam debian / ubuntu) gagal ketika menggunakan function
kata kunci.
function baz { echo "baz"; }
. Lihat Bashism di wiki GreyCat.Jawaban:
Tidak ada perbedaan AFAIK, selain fakta bahwa versi kedua lebih portabel.
sumber
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
tidak memperingatkan mereka untuk memeriksa ulang terlebih dahulu apakah versi tar di desthost akan menghilangkan "/" dapat menyebabkan bencana dalam beberapa kasus ...). Misalnya: jika menggunakanfunction tar { #a safe tar with safety checks ... }
dansh
mengabaikannya, ...sh
mengenalifunction
kata kunci - dan, secara umum, yang mengasumsikan fitur umum tetapi tidak standar yang disukaiksh
danbash
ditawarkan oleh shell - juga akan sering tidak bekerja pada sistem produksi yang lebih baru , bahkan jika mereka bekerja pada rilis yang lebih lama dari OS yang sama.bash
masih menyediakansh
pada banyak sistem GNU / Linux, tetapi beberapa distro populer telah beralih kesh
symlink kedash
(Debian Almquist SHell) untuk meningkatkan kinerja. Ini termasuk Debian dan Ubuntu .Kata
function
kunci diperkenalkan di ksh . Shell Bourne tradisional hanya memilikifoo ()
sintaks, dan POSIX hanya membakukanfoo ()
sintaks.Dalam ATT ksh (tetapi bukan pdksh), ada beberapa perbedaan antara fungsi yang didefinisikan oleh
function
dan fungsi yang didefinisikan dengan sintaks Bourne / POSIX. Dalam fungsi yang ditentukan olehfunction
,typeset
kata kunci mendeklarasikan variabel lokal: begitu fungsi keluar, nilai variabel diatur ulang ke apa sebelum memasukkan fungsi. Dengan sintaksis klasik, variabel memiliki cakupan global baik Anda gunakantypeset
atau tidak.Perbedaan lain dalam ksh adalah bahwa fungsi yang didefinisikan dengan
function
kata kunci memiliki konteks perangkapnya sendiri. Jebakan yang ditentukan di luar fungsi diabaikan saat menjalankan fungsi, dan kesalahan fatal di dalam fungsi keluar hanya fungsi dan bukan dari keseluruhan skrip. Juga,$0
adalah nama fungsi dalam fungsi yang ditentukan olehfunction
tetapi nama skrip dalam fungsi yang didefinisikan()
.Pdksh tidak meniru ATT ksh. Dalam pdksh,
typeset
membuat variabel cakupan lokal terlepas dari fungsi, dan tidak ada jebakan lokal (meskipun menggunakanfunction
memang membuat beberapa perbedaan kecil - lihat halaman manual untuk detail).Bash dan zsh memperkenalkan
function
kata kunci untuk kompatibilitas dengan ksh. Namun dalam shell inifunction foo { … }
danfoo () { … }
sangat identik, seperti ekstensi bash dan zshfunction foo () { … }
. Katatypeset
kunci selalu mendeklarasikan variabel lokal (kecuali dengan-g
tentu saja), dan jebakan bukan lokal (Anda bisa mendapatkan jebakan lokal di zsh dengan mengaturlocal_traps
opsi).sumber
foo() command
sintaksnya, dan sintaks Bourne kemudian ditambahkan ke shell Korn untuk kompatibilitas.function { ... }; f;
menghilangkanf
setelahfunction
kata kunci?adalah sintaks Bourne yang didukung oleh shell seperti Bourne tetapi
bash
,yash
dan versi terbaru dariposh
(yang hanya mendukung perintah majemuk). (Shell Bourne dan implementasi AT&Tksh
tidak mendukungfoo() any-command > redirections
kecualiany-command
perintah majemuk).(contoh senyawa perintah:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... makhluk yang paling umum digunakan{ ...; }
)adalah sintaks POSIX yang didukung oleh shell seperti Bourne dan yang umumnya ingin Anda gunakan.
adalah sintaks shell Korn, yang mendahului sintaks Bourne. Hanya gunakan yang ini jika menulis secara spesifik untuk implementasi AT&T dari shell Korn dan perlu perlakuan khusus yang diterimanya di sana. Sintaks itu bukan POSIX, tetapi didukung oleh
bash
,yash
danzsh
untuk kompatibilitas dengan shell Korn meskipun shell tersebut (danpdksh
varian berbasis shell Korn) tidak memperlakukannya berbeda dari sintaks standar.adalah sintaks dari no shell dan tidak boleh digunakan . Itu hanya terjadi harus didukung secara tidak sengaja oleh
bash
,yash
,zsh
danpdksh
varian berdasarkan dari shell Korn. Kebetulan, itu jugaawk
sintaks fungsi.Jika kita terus turun daftar esoteris,
(suka
function foo() (subshell)
ataufunction foo() for i do; ... done
) bahkan lebih buruk. Ini didukung olehbash
,yash
danzsh
, tetapi bukan ksh, bahkanpdksh
varian berbasis.Sementara:
hanya didukung oleh
zsh
.sumber
function
kata kunci dan tanda kurung didokumentasikan dalam Bash. Manual Bash 4.2 dan yang lebih baru mengatakan bahwa fungsi dideklarasikan oleh sintaksname () compound-command [ redirections ]
ataufunction name [()] compound-command [ redirections ]
. Dalam Bash 4.1.11 turun ke setidaknya 3.0-beta yang hanya satu baris[ function ] name () compound-command [redirection]
yang keliru tidak mencakup sintaksis yang mencakupfunction
kata kunci tetapi tidak tanda kurung tetapi masih mencakup sintaksis yang mencakupfunction
kata kunci dan tanda kurung.bash
mengenalifunction foo {
selainfoo() {
untuk kompatibilitas dengan shell Korn (dan selalu memiliki) sehingga dapat menafsirkan skrip yang ditulis untuk shell Korn. Itu memang mendukungfunction foo () {
juga, tetapi tidak ada alasan bagus untuk menggunakannya.function f() {
. Yaitu, dalam hal keterbacaan, itu akan diakui sebagai fungsi oleh siapa saja yang tahu bahasa Inggris dan siapa saja yang tahu C, dibandingkan hanya satu dari set ini.You should never combine the keyword function with the parentheses () when defining a function.
Secara semantik, kedua bentuk itu setara dalam Bash.
Dari halaman manual:
EDIT: Saya baru saja memperhatikan bahwa pertanyaan ini ditandai
posix
. Dalam POSIXsh
,function
kata kunci tidak digunakan (meskipun dicadangkan).sumber
Beberapa orang lain telah menjawab dengan benar sekarang, tetapi inilah sinopsis singkat saya:
Versi kedua adalah portabel dan cenderung bekerja dengan banyak shell standar (terutama POSIX).
Versi pertama hanya akan bekerja dengan bash, tetapi Anda dapat menghilangkan tanda kurung mengikuti nama fungsi dengannya.
Jika tidak, mereka mewakili entitas yang identik setelah bash menginterpretasikannya.
sumber
()
dan yangfunction
kata kunci shell berperilaku seolah-olah Anda baru saja melakukannyafoo(){ ...; }
pula, kecuali, tentu saja, untuk shell di mana itu adalah sintaks tidak valid. dan jadi Anda harus melakukannyafunction foo { ...; }
jika Anda harus, ataufoo(){ ...; }
sebaliknya.