Apakah fungsi dijalankan sebagai subproses di Bash?


28

Di Advanced Bash-Scripting Guide , misalnya 27-4 , baris ke-7 dari bawah, saya telah membaca ini:

Suatu fungsi berjalan sebagai sub-proses.

Saya melakukan tes di Bash, dan sepertinya pernyataan di atas salah.

Pencarian di situs ini, Bash Man, dan mesin pencari saya tidak membawa cahaya.

Apakah Anda punya jawaban dan ingin menjelaskan?


12
Sebagaimana dicatat, panduan itu menyesatkan secara ekstrem. Saya merekomendasikan Woolash Bash Guide sebagai gantinya.
Wildcard

Jawaban:


36

Panduan Bash-Scripting Lanjutan tidak selalu dapat diandalkan dan skrip contohnya berisi praktik out-tanggal seperti menggunakan backticks yang sudah tidak digunakan lagi untuk substitusi perintah, yaitu, `command`daripada $(command).

Dalam kasus khusus ini, itu sangat salah.

Bagian tentang Fungsi Shell dalam manual Bash (kanonik) secara pasti menyatakan itu

Fungsi Shell dijalankan dalam konteks shell saat ini; tidak ada proses baru yang dibuat untuk menafsirkannya.


10
"Panduan Script Bash Lanjutan umumnya tidak dapat diandalkan" Sangat benar.
John1024

1
Bisakah Anda memberikan referensi untuk mendukung kalimat pertama Anda?
Will Vousden

5
@ WillVousden apa yang akan terlihat seperti referensi di sini? Banyak contoh kekurangan teknis panduan ini? Sebuah dokumen di mana para ahli dalam komunitas bash sebelumnya mencatat bahwa itu tidak dapat diandalkan? Apakah akan membantu jika anggota stackoverflow dengan lencana emas di bash hanya setuju dalam komentar? : p
kojiro

3
@ WillVousden Saya tidak berpikir apa yang Anda inginkan ada dalam bentuk yang dapat diandalkan itu sendiri. Mendel Cooper telah memperbarui dan memperbaiki masalah dengan panduan ini di masa lalu, tetapi tidak ada pelacak bug publik atau daftar errata. (Mungkin itu adalah pernyataan paling memberatkan yang bisa saya buat.) Jadi, ketika kita menemukan cacat (yang dirasakan atau nyata) yang bisa kita lakukan adalah mengirimkan email kepada penulis dan berharap yang terbaik.
kojiro

3
@ WillVousden, ... jika Anda ingin sejarah berapa lama konsensus dalam saluran #bash freenode telah bahwa ABS harus dihindari, lihat wooledge.org/~greybot/meta/abs - bidang kedua di setiap baris adalah timestamp, dan yang pertama adalah nama pengguna; Saya akan berharap pernyataan bahwa nama pengguna yang dimaksud adalah individu yang sangat dihormati cukup.
Charles Duffy

32

Fungsi kurung kurawal akan berjalan dalam proses shell panggilan, kecuali jika mereka membutuhkan subkulit mereka sendiri yaitu:

  • ketika Anda menjalankannya di latar belakang dengan &
  • ketika Anda menjalankannya sebagai tautan di saluran pipa

Pengalihan atau env ekstra. variabel tidak akan memaksa subkulit baru:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

Jika Anda mendefinisikan fungsi dengan tanda kurung alih-alih ikal:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

itu akan selalu berjalan dalam proses baru.

Substitusi perintah $()juga selalu membuat proses dalam bash (tetapi tidak dalam ksh jika Anda menjalankan builtin di dalamnya).


Saya tidak tahu f() (...)diizinkan. Apakah ada definisi lain selain {...}dan (...)? Di Bash, saya belum menyukai orang lain.
Tomasz

1
@tomas Anda dapat menggunakan function hw { echo hello world; } sintaks (tidak perlu ()jika Anda mengetik functiondan Anda dapat menentukan pengalihan tepat setelah final }atau )seperti pada hw(){ echo error; } >&2. Itu saja.
PSkocik

2
Ini adalah jawaban yang langsung saya pikirkan, dan itu benar sekali. Itu harus dipilih sebagai jawaban yang benar. f()(...)selalu jalankan shell sendiri, sementara f(){...}tidak.
rexkogitans

11
Fungsi NB bash menerima perintah majemuk, jadi foo() [[ x = x ]]definisi fungsi juga valid. Namun, jika Anda melihat fungsinya dengan type fooAnda akan melihat bahwa ini masih gula sintaksis untuk foo() { [[ x = x ]]; }. Hal yang sama berlaku untuk fungsi subkulit: bar() ( : )menjadi bar() { ( : ); }.
kojiro

1
@kojiro bagus +1. tidak tahu itu
PSkocik

9

Perintah yang dimaksud dari contoh itu terlihat seperti:

echo ${arrayZ[@]/%e/$(replacement)}

Contohnya nanti menyatakan:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

Menjadi dermawan untuk ABS Guide, apa yang tampaknya dimaksudkan untuk ditulis adalah bahwa fungsi berjalan di dalam substitusi perintah dan perintah di dalam substitusi perintah berjalan dalam sebuah subkulit .


Itu sangat menyesatkan. Terima kasih atas interpretasi Anda.
Tomasz

5
@ Thomas "sangat menyesatkan." Ya sangat Berbeda dengan ABS Guide, Greg's Wiki adalah sumber informasi bash tingkat lanjut yang bagus.
John1024

1
Tepuk tangan. Apa pendapat Anda tentang ini: wiki.bash-hackers.org/start ?
Tomasz

@ Thomas Saya tidak memiliki pengetahuan langsung tentang itu.
John1024

2
@ Thomas, ... pendapat saya sendiri tentang wiki bash-hacker adalah bahwa itu adalah sumber yang sangat baik. Saya belum melewatinya secara komprehensif seperti halnya saya memiliki wiki Wooledge, tetapi cenderung akurat dan ditulis dengan tepat.
Charles Duffy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.