Apa kegunaan perintah exec dalam skrip shell?

250

Adakah yang bisa menjelaskan apa kegunaan perintah exec dalam skrip shell dengan contoh sederhana?

pengguna2400564
sumber
31
Tautan ke linux.about.com tidak membantu. Mereka tidak membuatnya jelas bagaimana mengeksekusi perintah atau pipa perintah menggunakan 'exec' berbeda dari hanya mengeksekusi mereka secara normal. Oleh karena itu pertanyaan OP "apa gunanya eksekutif"?
Jonathan Hartley
2
Stack Overflow adalah situs untuk pertanyaan pemrograman dan pengembangan. Pertanyaan ini tampaknya di luar topik karena ini bukan tentang pemrograman atau pengembangan. Lihat Topik apa yang bisa saya tanyakan di sini di Pusat Bantuan. Mungkin Super User atau Unix & Linux Stack Exchange akan menjadi tempat yang lebih baik untuk bertanya.
jww

Jawaban:

281

Perintah execbuilt-in mencerminkan fungsi-fungsi di kernel, ada satu keluarga berdasarkan execve, yang biasanya dipanggil dari C.

execmenggantikan program saat ini dalam proses saat ini, tanpa forkproses baru. Ini bukan sesuatu yang akan Anda gunakan dalam setiap skrip yang Anda tulis, tetapi kadang-kadang berguna. Berikut adalah beberapa skenario yang telah saya gunakan;

  1. Kami ingin pengguna menjalankan program aplikasi tertentu tanpa akses ke shell. Kami dapat mengubah program masuk di / etc / passwd, tapi mungkin kami ingin pengaturan lingkungan digunakan dari file start-up. Jadi, dalam (katakanlah) .profile, pernyataan terakhir mengatakan sesuatu seperti:

     exec appln-program

    jadi sekarang tidak ada shell untuk kembali. Bahkan jika appln-programcrash, pengguna akhir tidak bisa mendapatkan shell, karena tidak ada - execdiganti.

  2. Kami ingin menggunakan shell yang berbeda dengan yang ada di / etc / passwd. Bodoh seperti yang terlihat, beberapa situs tidak mengizinkan pengguna untuk mengubah shell masuk mereka. Satu situs yang saya tahu memiliki semua orang mulai dengan csh, dan semua orang hanya .loginpanggilan (csh start-up file) panggilan mereka ksh. Sementara itu berhasil, ia meninggalkan cshproses nyasar berjalan, dan logout adalah dua tahap yang bisa membingungkan. Jadi kami mengubahnya exec kshyang baru saja mengganti program c-shell dengan korn shell, dan membuat semuanya lebih sederhana (ada masalah lain dengan ini, seperti fakta bahwa kshitu bukan shell-login).

  3. Hanya untuk menghemat proses. Jika kita memanggil prog1 -> prog2 -> prog3 -> prog4dll dan tidak pernah kembali, maka buat setiap panggilan sebagai exec. Menghemat sumber daya (tidak banyak, diakui, kecuali diulang) dan membuat shutdown lebih mudah.

Anda jelas telah melihat execdigunakan di suatu tempat, mungkin jika Anda menunjukkan kode yang mengganggu Anda, kami dapat membenarkan penggunaannya.

Sunting : Saya menyadari bahwa jawaban saya di atas tidak lengkap. Ada dua penggunaan execdi shell seperti kshdan bash- digunakan untuk membuka deskriptor file. Berikut ini beberapa contohnya:

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Perhatikan bahwa spasi sangat penting di sini. Jika Anda menempatkan spasi antara angka fd dan simbol pengalihan maka execkembali ke makna aslinya:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Ada beberapa cara Anda dapat menggunakan ini, pada penggunaan ksh read -uatau print -u, pada bash, misalnya:

read <&3
echo stuff >&4
cdarke
sumber
22
ada juga kegunaan lain yang saya temukan sangat berguna dan layak disebutkan di sini karena ini berkaitan dengan aplikasi web python dan sepertinya ada sesuatu di antara jawaban (mengagumkan) Anda 2 dan 3. Saya biasanya menjalankan aplikasi web wsgi (katakan Django atau labu) melalui penyelia yang memanggil Gunicorn app: yang terakhir ini terkenal membutuhkan beberapa variabel lingkungan, itu cara yang lebih mudah dan lebih baik menjalankan gunicorn dari skrip shell yang mengatur semuanya dan akhirnya exec gunicornmemberikan pid yang benar kembali ke penyelia.
gru
1
The docs mengatakan bahwa execdapat digunakan untuk pengalihan:> Jika perintah tidak ditentukan, setiap pengalihan berlaku di shell saat ini, dan status kembali adalah 0. Jika ada kesalahan pengalihan, status kembali adalah 1. Tapi bagaimana melakukan execsebenarnya bekerja untuk mengubah file descriptor? Mengapa perintah khusus ini dipilih untuk tugas ini? (Penurunan harga gagal sekarang?)
Ray
@ Ray: terbaik yang bisa saya lakukan: pubs.opengroup.org/onlinepubs/009604599/utilities/exec.html . Jika Anda perlu tahu caranya, lihat kode sumber shell.
cdarke
7
Penggunaan lain: Mengarahkan ulang semua hasil skrip ke logfileexec >.\logfilename.log 2>&1
Hogan
1
@Carmageddon: &>adalah bashekstensi (lihat man bash) dan contoh Anda setara dengan exec >/var/log/userdata.log 2>&1. Dengan kata lain itu mengarahkan stdout dan stderr ke file itu. Perintah yang mengikuti akan mewarisi pengalihan tersebut kecuali jika disetel ulang, tetapi akan dieksekusi.
cdarke
41

Hanya untuk menambah jawaban yang diterima dengan jawaban singkat ramah-pemula yang singkat, Anda mungkin tidak perlu exec.

Jika Anda masih di sini, diskusi berikut semoga mengungkap alasannya. Ketika Anda berlari, katakan,

sh -c 'command'

Anda menjalankan sebuah shinstance, lalu mulai commandsebagai anak dari shinstance itu. Saat commandselesai, shinstance juga selesai.

sh -c 'exec command'

menjalankan shcontoh, kemudian menggantikan bahwa shmisalnya dengan commandbiner, dan berjalan yang sebaliknya.

Tentu saja, keduanya tidak berguna dalam konteks terbatas ini; Anda hanya ingin

command

Ada beberapa situasi pinggiran di mana Anda ingin shell membaca file konfigurasinya atau entah bagaimana mengatur lingkungan sebagai persiapan untuk menjalankan command. Ini adalah satu-satunya situasi di mana exec commandberguna.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

Ini melakukan beberapa hal untuk mempersiapkan lingkungan sehingga mengandung apa yang dibutuhkan. Setelah selesai, shinstance tidak lagi diperlukan, dan itu merupakan optimasi (minor) untuk hanya mengganti shinstance dengan commandproses, daripada shmenjalankannya sebagai proses anak dan menunggu untuk itu, kemudian keluar segera setelah selesai.

Demikian pula, jika Anda ingin membebaskan sumber daya sebanyak mungkin untuk perintah yang berat di akhir skrip shell, Anda mungkin ingin execperintah itu sebagai optimasi.

Jika ada sesuatu yang memaksa Anda untuk berlari shtetapi Anda benar-benar ingin menjalankan sesuatu yang lain, exec something elsetentu saja merupakan solusi untuk mengganti shinstance yang tidak diinginkan (seperti misalnya jika Anda benar-benar ingin menjalankan spiffy Anda sendiri goshalih-alih shtetapi milik Anda tidak terdaftar /etc/shellssehingga Anda dapat tentukan sebagai shell login Anda).

Penggunaan kedua execuntuk memanipulasi deskriptor file adalah topik yang terpisah. Jawaban yang diterima mencakup hal itu dengan baik; untuk menjaga ini mandiri, saya hanya akan tunduk pada manual untuk apa pun execyang diikuti dengan pengalihan alih-alih nama perintah.

tripleee
sumber
2
Menolak godaan untuk memanggil cangkang Anda yang licin bush. Tentu saja, ini berlaku untuk bashatau pada umumnya shell Unix yang populer juga; meskipun seperti catatan @anishsane , Bash diam-diam mengoptimalkan bash -c 'command'dengan benar-benar melakukannya exec command.
tripleee
1
Kode keluar dari shell umumnya adalah kode keluar dari perintah terakhir yang dijalankan. Tentu saja, jika shell gagal dijalankan, atau untuk menjalankan perintah, status keluar shell akan mencerminkannya dengan kode kesalahan yang sesuai.
tripleee
2
@ JonathanLeffler Saya sengaja mendokumentasikan antipattern yang saya lihat di pertanyaan pemula. Yang ini didorong oleh duplikat ini tetapi saya telah melihatnya sebelumnya, jadi saya ingin membahasnya secara khusus.
tripleee
2
@JonathanLeffler Minor mengubah kata-kata; apakah ini cukup, menurut Anda? Terima kasih untuk umpan baliknya.
tripleee
2
Terima kasih - saya menambahkan paragraf singkat lain tentang pengoptimalan ini. Tidak terlalu jelas bagi saya jika Anda memiliki keberatan lain, atau jika Anda hanya ingin menjelaskan sesuatu dari sudut yang berbeda.
tripleee