Versi 2004 dari POSIX system() dokumentasi memiliki alasan yang mungkin berlaku untuk popen() demikian juga. Perhatikan batasan yang disebutkan pada system() , terutama yang menyatakan "bahwa ID prosesnya berbeda":
RASIONAL
...
Ada tiga tingkat spesifikasi untuk fungsi system(). Standar ISO C memberikan yang paling dasar. Itu membutuhkan fungsi yang ada, dan menentukan cara bagi aplikasi untuk menanyakan apakah juru bahasa perintah ada. Tidak disebutkan apa pun tentang bahasa perintah atau lingkungan tempat perintah tersebut ditafsirkan.
IEEE Std 1003.1-2001 memberikan batasan tambahan pada system(). Itu membutuhkan jika ada juru bahasa perintah, lingkungan harus seperti yang ditentukan oleh fork() dan exec. Ini memastikan, misalnya, bahwa close-on-exec berfungsi, bahwa kunci file tidak diwariskan, dan ID prosesnya berbeda. Ini juga menentukan nilai kembalian dari system() saat baris perintah dapat dijalankan, sehingga memberi aplikasi beberapa informasi tentang status penyelesaian perintah.
Terakhir, IEEE Std 1003.1-2001 mengharuskan perintah untuk ditafsirkan seperti dalam bahasa perintah shell yang ditentukan dalam volume Shell and Utilities dari IEEE Std 1003.1-2001.
Perhatikan beberapa referensi ke "Standar ISO C". Versi terbaru standar C mengharuskan string perintah diproses oleh "pemroses perintah" sistem:
7.22.4.8
systemfungsiSinopsis
#include <stdlib.h> int system(const char *string);Deskripsi
Jika
stringadalah pointer null,systemfungsi menentukan apakah lingkungan host memiliki prosesor perintah. Jikastringbukan penunjuk null,systemfungsi melewati string yang ditunjuk olehstringkepada pemroses perintah untuk dieksekusi dengan cara yang pelaksanaannya harus didokumentasikan; ini kemudian dapat menyebabkan program memanggilsystemuntuk berperilaku dengan cara yang tidak sesuai atau untuk menghentikan.Pengembalian
Jika argumennya adalah pointer null,
systemfunction mengembalikan nol hanya jika prosesor perintah tersedia. Jika argumennya bukan penunjuk nol, dansystemfunctiontidak mengembalikan, mengembalikan nilai yang ditentukan implementasi.
Karena standar C mengharuskan sistem "pemroses perintah" digunakan untuk system() panggilan, saya menduga bahwa:
- Di suatu tempat ada persyaratan di POSIX yang mengikat
popen()kesystem()implementasi. - Lebih mudah menggunakan kembali "pemroses perintah" sepenuhnya karena ada juga persyaratan untuk dijalankan sebagai proses terpisah.
Jadi ini adalah jawaban fasih yang dihapus dua kali.
Memanggil shell memungkinkan Anda melakukan semua hal yang dapat Anda lakukan di shell.Misalnya,
FILE *fp = popen("ls *", "r");
dimungkinkan dengan popen() (memperluas semua file di direktori saat ini). Bandingkan dengan:
execvp("/bin/ls", (char *[]){"/bin/ls", "*", NULL});
Anda tidak dapat menjalankan ls dengan * sebagai argumen karena exec(2) akan menafsirkan * secara harfiah.
Demikian pula, pipa (| ), pengalihan (> , < , ...), dll., dimungkinkan dengan popen .
Jika tidak, tidak ada alasan untuk menggunakan popen jika Anda tidak membutuhkan shell - itu tidak perlu. Anda akan berakhir dengan proses shell ekstra dan semua hal yang bisa salah di shell bisa salah dalam program Anda (misalnya, perintah yang Anda berikan dapat diinterpretasikan secara tidak benar oleh shell dan masalah keamanan umum). popen() dirancang seperti itu. fork + exec solusi lebih bersih tanpa masalah yang terkait dengan shell.
Jawaban fasih adalah karena standar POSIX ( http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ) mengatakan demikian. Atau lebih tepatnya, ia mengatakan bahwa ia harus berperilaku seolah-olah argumen perintah diteruskan ke /bin/sh untuk interpretasi.
Jadi saya kira implementasi yang sesuai dapat, pada prinsipnya, juga memiliki beberapa fungsi perpustakaan internal yang akan menginterpretasikan perintah shell tanpa harus melakukan fork dan menjalankan proses shell yang terpisah. Saya sebenarnya tidak mengetahui penerapan semacam itu, dan saya menduga memperbaiki semua kasus sudut akan sangat rumit.