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;
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.
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).
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:
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?)
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.
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.
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.
Jawaban:
Perintah
exec
built-in mencerminkan fungsi-fungsi di kernel, ada satu keluarga berdasarkanexecve
, yang biasanya dipanggil dari C.exec
menggantikan program saat ini dalam proses saat ini, tanpafork
proses 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;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:jadi sekarang tidak ada shell untuk kembali. Bahkan jika
appln-program
crash, pengguna akhir tidak bisa mendapatkan shell, karena tidak ada -exec
diganti.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.login
panggilan (csh start-up file) panggilan merekaksh
. Sementara itu berhasil, ia meninggalkancsh
proses nyasar berjalan, dan logout adalah dua tahap yang bisa membingungkan. Jadi kami mengubahnyaexec ksh
yang baru saja mengganti program c-shell dengan korn shell, dan membuat semuanya lebih sederhana (ada masalah lain dengan ini, seperti fakta bahwaksh
itu bukan shell-login).Hanya untuk menghemat proses. Jika kita memanggil
prog1 -> prog2 -> prog3 -> prog4
dll 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
exec
digunakan 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
exec
di shell sepertiksh
danbash
- digunakan untuk membuka deskriptor file. Berikut ini beberapa contohnya:Perhatikan bahwa spasi sangat penting di sini. Jika Anda menempatkan spasi antara angka fd dan simbol pengalihan maka
exec
kembali ke makna aslinya:Ada beberapa cara Anda dapat menggunakan ini, pada penggunaan ksh
read -u
atauprint -u
, padabash
, misalnya:sumber
exec gunicorn
memberikan pid yang benar kembali ke penyelia.exec
dapat 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 melakukanexec
sebenarnya bekerja untuk mengubah file descriptor? Mengapa perintah khusus ini dipilih untuk tugas ini? (Penurunan harga gagal sekarang?)exec >.\logfilename.log 2>&1
&>
adalahbash
ekstensi (lihatman bash
) dan contoh Anda setara denganexec >/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.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,
Anda menjalankan sebuah
sh
instance, lalu mulaicommand
sebagai anak darish
instance itu. Saatcommand
selesai,sh
instance juga selesai.menjalankan
sh
contoh, kemudian menggantikan bahwash
misalnya dengancommand
biner, dan berjalan yang sebaliknya.Tentu saja, keduanya tidak berguna dalam konteks terbatas ini; Anda hanya ingin
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 manaexec command
berguna.Ini melakukan beberapa hal untuk mempersiapkan lingkungan sehingga mengandung apa yang dibutuhkan. Setelah selesai,
sh
instance tidak lagi diperlukan, dan itu merupakan optimasi (minor) untuk hanya menggantish
instance dengancommand
proses, daripadash
menjalankannya 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
exec
perintah itu sebagai optimasi.Jika ada sesuatu yang memaksa Anda untuk berlari
sh
tetapi Anda benar-benar ingin menjalankan sesuatu yang lain,exec something else
tentu saja merupakan solusi untuk menggantish
instance yang tidak diinginkan (seperti misalnya jika Anda benar-benar ingin menjalankan spiffy Anda sendirigosh
alih-alihsh
tetapi milik Anda tidak terdaftar/etc/shells
sehingga Anda dapat tentukan sebagai shell login Anda).Penggunaan kedua
exec
untuk 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 punexec
yang diikuti dengan pengalihan alih-alih nama perintah.sumber
bush
. Tentu saja, ini berlaku untukbash
atau pada umumnya shell Unix yang populer juga; meskipun seperti catatan @anishsane , Bash diam-diam mengoptimalkanbash -c 'command'
dengan benar-benar melakukannyaexec command
.