Saya mencari cara untuk mendapatkan output dari sebuah perintah ketika dijalankan dari dalam program C ++. Saya telah melihat menggunakan system()
fungsi, tetapi itu hanya akan menjalankan perintah. Berikut ini contoh yang saya cari:
std::string result = system("./some_command");
Saya perlu menjalankan perintah arbitrer dan mendapatkan hasilnya. Saya telah melihat boost.org , tetapi saya belum menemukan apa pun yang akan memberikan apa yang saya butuhkan.
/programming/52164723/how-to-execute-a-command-and-get-return-code-stdout-and-stderr-of-command-in-c
untuk perpanjangan dari jawaban hebat di bawah ini yang menyediakan metode untuk mendapatkanreturn code
danstderr
jugastdout
jawaban ini sudah menjelaskanJawaban:
Versi Pra-C ++ 11:
Ganti
popen
danpclose
dengan_popen
dan_pclose
untuk Windows.sumber
result += buffer
, sehingga pipa mungkin tidak ditutup dengan benar.int main(){ puts("ERROR"); }
.Mendapatkan stdout dan stderr (dan juga menulis ke stdin, tidak ditampilkan di sini) mudah dikenali dengan header pstreams saya , yang mendefinisikan kelas iostream yang berfungsi seperti
popen
:sumber
popen
mengharuskan Anda untuk menggunakan C stdio API, saya lebih suka API iostreams.popen
mengharuskan Anda membersihkanFILE
pegangan secara manual , pstreams melakukannya secara otomatis.popen
hanya menerimaconst char*
argumen, yang membutuhkan kehati-hatian untuk menghindari serangan injeksi shell, pstreams memungkinkan Anda untuk mengirim vektor string yang serupaexecv
, yang lebih aman.popen
memberi Anda apa-apa selain pipa, pstreams memberi tahu Anda PID anak yang memungkinkan Anda mengirim sinyal misalnya membunuhnya jika terhalang atau tidak keluar. Semua itu adalah keuntungan bahkan jika Anda hanya menginginkan IO searah.pstreambuf::in_avail()
, jadi tidak akan memblokir. Itu memungkinkan demultiplexing pada stdout dan stderr proses karena masing-masing memiliki data yang tersedia.pstreambuf::in_avail()
hanya berfungsi 100% andal jika OS mendukung FIONREAD ioctl non-standar, tetapi itu didukung pada (setidaknya) GNU / Linux dan Solaris.Saya akan menggunakan popen () (++ waqas) .
Tetapi kadang-kadang Anda perlu membaca dan menulis ...
Sepertinya tidak ada yang melakukan hal-hal yang sulit lagi.
(Dengan asumsi lingkungan Unix / Linux / Mac, atau mungkin Windows dengan lapisan kompatibilitas POSIX ...)
Anda juga mungkin ingin bermain-main dengan bacaan pilih () dan non-pemblokiran.
sumber
execlp
Panggilan Anda memiliki bug:arg
penunjuk terakhir yang dilewati harus(char *) NULL
mengakhiri daftar argumen variadik dengan benar (lihatexeclp(3)
untuk referensi).Untuk Windows,
popen
juga berfungsi, tetapi membuka jendela konsol - yang dengan cepat membuka aplikasi UI Anda. Jika Anda ingin menjadi seorang profesional, lebih baik menonaktifkan "flashing" ini (terutama jika pengguna akhir dapat membatalkannya).Jadi di sini adalah versi saya sendiri untuk Windows:
(Kode ini sebagian direkombinasi dari ide-ide yang ditulis dalam The Code Project dan sampel MSDN.)
sumber
wchar_t
danCreateProcessW
sebagai batasan yang tidak perlu.The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
Jadi mungkin lebih baik untuk menyalin baris perintah ke buffer terpisah terlebih dahulu, untuk mencegah penelepon dari mendapatkan input aslinya diubah.Dua kemungkinan pendekatan:
Saya tidak berpikir itu
popen()
adalah bagian dari standar C ++ (ini bagian dari POSIX dari memori), tetapi tersedia di setiap UNIX yang pernah saya gunakan (dan Anda sepertinya menargetkan UNIX karena perintah Anda./some_command
).Jika tidak ada
popen()
, Anda dapat menggunakansystem("./some_command >/tmp/some_command.out");
, lalu gunakan fungsi I / O normal untuk memproses file output.sumber
Saya tidak tahu mengapa popen / pclose hilang dari Code :: Blocks / MinGW. Jadi saya mengatasi masalah dengan menggunakan CreateProcess () dan CreatePipe () sebagai gantinya.
Inilah solusi yang bekerja untuk saya:
sumber
CREATE_NO_WINDOW
?ListStdErr
tidak pernah digunakan.Berikut ini mungkin solusi portabel. Ini mengikuti standar.
sumber
tmpnam
berbahaya, lebih baik digunakanmkstemp
"Dengan asumsi POSIX, kode sederhana untuk menangkap stdout:
Kontribusi kode diterima untuk lebih banyak fungsi:
https://github.com/ericcurtin/execxx
sumber
Anda bisa mendapatkan output setelah menjalankan skrip menggunakan pipa. Kami menggunakan pipa ketika kami ingin hasil dari proses anak.
Jadi inilah skrip yang ingin Anda jalankan. Masukkan ke dalam variabel perintah dengan argumen yang diambil skrip Anda (tidak ada jika tidak ada argumen). Dan file tempat Anda ingin mengambil output skrip, taruh di copy_fp.
Jadi popen menjalankan skrip Anda dan menempatkan output dalam fpipe dan kemudian Anda bisa menyalin semuanya dari itu ke file output Anda.
Dengan cara ini Anda dapat menangkap output dari proses anak.
Dan proses lainnya adalah Anda bisa langsung menempatkan
>
operator di perintah saja. Jadi jika kita akan meletakkan semuanya dalam file saat kita menjalankan perintah, Anda tidak perlu menyalin apa pun.Dalam hal ini, tidak perlu menggunakan pipa. Anda bisa menggunakan adil
system
, dan itu akan menjalankan perintah dan meletakkan output di file itu.Anda dapat membaca Tutorial YoLinux: Fork, Exec, dan Kontrol proses untuk informasi lebih lanjut.
sumber
Perhatikan bahwa Anda bisa mendapatkan output dengan mengarahkan output ke file dan kemudian membacanya
Itu ditunjukkan dalam dokumentasi
std::system
Anda dapat menerima kode keluar dengan memanggil
WEXITSTATUS
makro.sumber