GNU/Linux >> Belajar Linux >  >> Linux

Apakah Tanda Kurung Benar-benar Menempatkan Perintah Dalam Subkulit?

Dari apa yang saya baca, meletakkan perintah dalam tanda kurung harus menjalankannya dalam subkulit, mirip dengan menjalankan skrip. Jika ini benar, bagaimana cara melihat variabel x jika x tidak diekspor?

x=1

Menjalankan (echo $x) pada baris perintah menghasilkan 1

Menjalankan echo $x dalam skrip tidak menghasilkan apa-apa, seperti yang diharapkan

Jawaban yang Diterima:

Sebuah subkulit dimulai sebagai salinan yang hampir identik dari proses cangkang asli. Di bawah tenda, shell memanggil fork panggilan sistem, yang menciptakan proses baru yang kode dan memorinya disalin. Saat subkulit dibuat, hanya ada sedikit perbedaan antara subkulit itu dan induknya. Secara khusus, mereka memiliki variabel yang sama. Bahkan $$ variabel khusus menyimpan nilai yang sama dalam subkulit:ini adalah ID proses shell asli. Demikian pula $PPID adalah PID induk dari shell asli.

Beberapa shell mengubah beberapa variabel dalam subkulit. Bash mengatur BASHPID ke PID dari proses shell, yang berubah dalam subkulit. Bash, zsh dan mksh mengatur $RANDOM untuk menghasilkan nilai yang berbeda di induk dan di subkulit. Namun terlepas dari kasus khusus bawaan seperti ini, semua variabel memiliki nilai yang sama di subkulit seperti di cangkang asli, status ekspor yang sama, status hanya baca yang sama, dll. Semua definisi fungsi, definisi alias, opsi shell dan pengaturan lain juga diwariskan.

Sebuah subkulit yang dibuat oleh (…) memiliki deskriptor file yang sama dengan pembuatnya. Beberapa cara lain untuk membuat subkulit memodifikasi beberapa deskriptor file sebelum mengeksekusi kode pengguna; misalnya, sisi kiri pipa berjalan di subkulit dengan output standar yang terhubung ke pipa. Subkulit juga dimulai dengan direktori saat ini yang sama, topeng sinyal yang sama, dll. Salah satu dari sedikit pengecualian adalah bahwa subkulit tidak mewarisi perangkap khusus:sinyal yang diabaikan (trap '' SIGNAL ) tetap diabaikan di subkulit, tetapi jebakan lainnya (trap CODE SINYAL ) disetel ulang ke tindakan default.

Dengan demikian, subkulit berbeda dari menjalankan skrip. Skrip adalah program terpisah. Program terpisah ini mungkin secara kebetulan juga merupakan skrip yang dieksekusi oleh penerjemah yang sama dengan induknya, tetapi kebetulan ini tidak memberikan program terpisah visibilitas khusus apa pun pada data internal induknya. Variabel yang tidak diekspor adalah data internal, jadi ketika penerjemah untuk skrip shell anak dijalankan, variabel ini tidak terlihat. Variabel yang diekspor, yaitu variabel lingkungan, ditransmisikan ke program yang dieksekusi.

Jadi:

x=1
(echo $x)

mencetak 1 karena subkulit adalah replikasi dari cangkang yang melahirkannya.

x=1
sh -c 'echo $x'

kebetulan menjalankan shell sebagai proses anak dari shell, tetapi x pada baris kedua tidak memiliki koneksi lagi dengan x di baris kedua daripada di

x=1
perl -le 'print $x'

atau

x=1
python -c 'print x'

Pengecualian adalah ksh93 shell tempat forking dioptimalkan dan sebagian besar efek sampingnya ditiru.
Secara semantik, mereka adalah salinan. Dari perspektif implementasi, ada banyak berbagi yang terjadi.
Untuk sisi kanan, tergantung cangkangnya.
Jika Anda menguji ini, perhatikan bahwa hal-hal seperti $(trap) dapat melaporkan jebakan cangkang asli. Perhatikan juga bahwa banyak cangkang memiliki bug dalam kasus sudut yang melibatkan jebakan. Misalnya ninjalj mencatat bahwa pada bash 4.3, bash -x -c 'trap "echo ERR at $BASH_SUBSHELL $BASHPID" ERR; set -E; false; echo one subshell; (false); echo two subshells; ( (false) )' menjalankan ERR perangkap dari subkulit bersarang dalam kasus "dua subkulit", tetapi bukan ERR trap dari subkulit perantara — set -E opsi harus menyebarkan ERR trap ke semua subkulit tetapi subkulit perantara dioptimalkan sehingga tidak ada untuk menjalankan ERR perangkap.

Terkait:Linux – Mengapa setuid tidak berfungsi??
Linux
  1. Kuasai perintah Linux ls

  2. Bagaimana Cara Menetapkan Output Perintah Ke Variabel Shell?

  3. Apa Perbedaan Get Command Output Menggunakan`command`dan $(command) Di Shell??

  1. Menggunakan perintah passwd dari dalam skrip shell

  2. Apa perbedaan antara &> dan >&di bash?

  3. Bagaimana cara menjalankan perintah Vim dari shell?

  1. Alias ​​baris perintah di Linux Shell

  2. Inti Dari Perintah Eksternal `cd`?

  3. Sembunyikan output dari perintah shell hanya jika berhasil?