Giriş
Şu satır dahil edilir.
Çalıştırılan uygulamanın ya stdout veya stdin akımını alır. sterr akımını kullanmaz!
İmzası
İmzası şöyledir.
popen "r" ile çağrılmışsa child process çalışmaya başladıktan sonra yaratılmış olan pipe'ın okuma ucu STDOUT_FILENO ile yer değiştiriyor.
Şu satır dahil edilir.
#include <stdio.h>
popen metoduÇalıştırılan uygulamanın ya stdout veya stdin akımını alır. sterr akımını kullanmaz!
İmzası
İmzası şöyledir.
FILE *popen(const char *command, const char *type);
type alanına "r" veya "w" karakteri gelir. Açıklaması şöyle
Şöyle yaparız.
Eğer olmayan bir komut çalıştırılmaya çalışılırsa FILE* null dönmüyor. Bu durumda ne yapmak lazım bilmiyorum.
popen kabuğu kullanır
POSIX dokümanında da benzer yazı mevcut. Açıklaması şöyleThe type argument is a pointer to a null-terminated string which must contain either the letter 'r' for reading or the letter 'w' for writing.
Okumak İçinThe character 'b' shall have no effect, but is allowed for ISO C standard conformance.
Şöyle yaparız.
FILE* pipe = popen("...", "r");
Şu kod hatalı. Çünkü okuma akımı zaten binary açılır.FILE* pipe = popen("...", "rb");
Hata YakalamaEğer olmayan bir komut çalıştırılmaya çalışılırsa FILE* null dönmüyor. Bu durumda ne yapmak lazım bilmiyorum.
popen kabuğu kullanır
popen() çağrısı std::system() çağrısına benzer şekilde alt tarafta fork() ile yeni bir child process oluşturuluyor ve child içinde yine aynı şekilde
execl(_PATH_BSHELL, "sh", "-c", program, NULL);
çağırılıyor. Ancak arada fark olarak child process yaratılmadan önce bir pipe oluşturuluyor.
int pdes[2];
pipe(pdes);
int pdes[2];
pipe(pdes);
close(pdes[0]);//Pipe'ın okuma ucunu kapat
(void)dup2(pdes[1], STDOUT_FILENO);//Pipe'ın yazma ucu stdout ile aynı olsun
(void)close(pdes[1]);//Pipe'ın yazma ucunu da kapat
Bu işlemin ardından çağırılan execl() ile çalıştırılan shell output stream olarak yaratılan pipe'a yazdığı için parent process'te child'ın çıktısını okuyabiliyor.
Burada dikkat edilmesi gereken nokta çalıştırılan uygulamanın ya stdin veya stdout akımının kullanılması, stderr akımı kullanılmıyor. Hepsini birden kullanmak için buraya bakabilirsiniz.
(void)close(pdes[1]);//Pipe'ın yazma ucunu da kapat
Bu işlemin ardından çağırılan execl() ile çalıştırılan shell output stream olarak yaratılan pipe'a yazdığı için parent process'te child'ın çıktısını okuyabiliyor.
Burada dikkat edilmesi gereken nokta çalıştırılan uygulamanın ya stdin veya stdout akımının kullanılması, stderr akımı kullanılmıyor. Hepsini birden kullanmak için buraya bakabilirsiniz.
Örnekler
Kendi script'imi çalıştırmak için şöyle yaparız.
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
FILE *in;
char buff[512];
if(!(in = popen("my_script_from_command_line", "r"))){
return 1;
}
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff; // here you have each line
// of the output of your script in buff
}
pclose(in);
return 0;
}
ls uygulamasını çalıştırmak için şöyle yaparız.#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *process;
char buff[1024];
process = popen("ls -l", "r");
if (process != NULL) {
while (!feof(process)) {
fgets(buff, sizeof(buff), process);
printf("%s", buff);
}
pclose(process);
}
return 0;
}
bash komutu çalıştırmak için şöyle yaparız.#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main ()
{
// get PATH using pipe
FILE* pip = popen("exec bash -c 'echo $PATH'", "r");
if (!pip)
{
printf("can not open pipe!");
return 1;
}
char lineversion[600];
memset (lineversion, 0, sizeof(lineversion));
if (!fgets(lineversion, sizeof(lineversion), pip))
{
printf("fgets error!");
return 1;
}
std::cout << lineversion << std::endl;
// get PATH using getenv
char* pPath = getenv ("PATH");
std::cout << pPath << std::endl;
}
_popen ve _pclose
Bu metod Windows'taki C kütüphanesinde bulunur. popen() ile hemen hemen aynıdır. Şöyle yaparız.
İşlem bitince FILE* pclose() ile kapatılmalıdır.
Bu metod Windows'taki C kütüphanesinde bulunur. popen() ile hemen hemen aynıdır. Şöyle yaparız.
const std::string command = ...;
FILE* output = _popen(command.c_str(), "r");
...
_pclose(output);
pclose metoduİşlem bitince FILE* pclose() ile kapatılmalıdır.
Hiç yorum yok:
Yorum Gönder