You are not logged in.

#1 2009-07-20 03:23:11

oib111
Member
Registered: 2009-06-20
Posts: 87

Executing Terminal Commands

I was wondering how I can execute commands you would normally run through a terminal (not just bash commands) through a C++ program? And how would I display the output of the command? I'm thinking fork() and execve()?

Offline

#2 2009-07-20 03:57:35

fumbles
Member
Registered: 2006-12-22
Posts: 246

Re: Executing Terminal Commands

system()

Offline

#3 2009-07-20 05:37:09

oib111
Member
Registered: 2009-06-20
Posts: 87

Re: Executing Terminal Commands

I'd rather not use system, any other alternatives?

Last edited by oib111 (2009-07-20 06:54:20)

Offline

#4 2009-07-20 08:30:36

tadzik
Member
From: &tadzik
Registered: 2009-07-17
Posts: 91

Re: Executing Terminal Commands

To fetch the output of the program You'll have to use pipe. Start from `man 3 popen`.
And neither fork() nor execve() will help you in any way. Fork justs forks Your program, it has nothing with running separate commands. And execve, afair subtitutes Your process with a shell command given.
Regards
Ted

Last edited by tadzik (2009-07-20 08:33:30)

Offline

#5 2009-07-20 12:13:46

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 990

Re: Executing Terminal Commands

@tadzik:  Actually, this is more or less the same thing.  Fork the program and have the child process do an execve().  It's essentially the same thing that system() does.

@oib11:  Why not use system?  You desire to catch the output in your program, or want to avoid calling an extra shell process?  Just curious.

Offline

#6 2009-07-20 18:26:06

oib111
Member
Registered: 2009-06-20
Posts: 87

Re: Executing Terminal Commands

I try to only use system when absolutely neccessary. This article is very informative. Also, I'll look into the pipes.

Offline

#7 2009-07-20 18:41:42

wuischke
Member
From: Suisse Romande
Registered: 2007-01-06
Posts: 630

Re: Executing Terminal Commands

oib111: If you permit, allow me to comment on this issue:

Your link has the following points:
1. resource heavy: Although this really shouldn't matter nowadays and it is only little different (if at all) compared to execvp/fork
2. security: absolutely correct, but no different with execvp/fork
3. anti-virus: not exactly valid for you.

What I believe the article wants to express is not that (only) system() is evil, but that calling external commands should be avoided if possible.

So you're completely right when you use it only when absolutely necessary and I recommend you to extend this to calling external commands in general.

Is there no library to accomplish what you want to do?

Offline

#8 2009-07-20 19:13:00

oib111
Member
Registered: 2009-06-20
Posts: 87

Re: Executing Terminal Commands

Thank you for the comment., and I'm not sure if there is a library for this. Also, this is my code so far:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    FILE *pipe;
    char *output;
    int bytesRead;
    size_t size = 1000;

    pipe = popen(argv[1], "r");
    if(!pipe) {
        std::cout<<"Unable to open pipe.";
        return 1;
    }
    output = (char *)malloc(size+1);
    bytesRead = getline(&output, &size, pipe);
    if(pclose(pipe) < 0) {
        std::cout<<"Could not run"<<argv[1]<<" or other error.";
        return 1;
    }
    std::cout<<output;
    std::cin.get();
    return 0;
}

Obviously getline only gets the first line of output. Is there a function that captures the whole output?

Last edited by oib111 (2009-07-20 19:19:14)

Offline

#9 2009-07-20 19:38:05

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Executing Terminal Commands

You would probably need to do something like,

while(!feof(pipe)) {
    bytesRead = getLine(&output, &size, pipe);
    // Do something with output, maybe strncat
}

Offline

#10 2009-07-20 20:59:18

oib111
Member
Registered: 2009-06-20
Posts: 87

Re: Executing Terminal Commands

Thanks. Here's the modified code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main(int argc, char *argv[]) {
    FILE *pipe;
    char *output;
    int bytesRead;
    size_t size = 100;

    pipe = popen(argv[1], "r");
    if(!pipe) {
        std::cout<<"Unable to open pipe.";
        return 1;
    }
    output = (char *)malloc(size+1);
    while(!feof(pipe) {
        bytesRead = getline(&output, &size, pipe);
        std::cout<output"\n";
    }
    if(pclose(pipe) < 0) {
        std::cout<<"Could not run"<<argv[1]<<" or other error.";
        return 1;
    }
    std::cin.get();
    return 0;
}

EDIT:

If I try making pipe a global variable I get "/home/isaac/documents/code/rtServer/main.cpp|10|error: 'FILE* pipe' redeclared as different kind of symbol|"....What's going on?

Last edited by oib111 (2009-07-20 21:36:52)

Offline

Board footer

Powered by FluxBB