2

I'm writing a program that needs to be able to execute a shell script provided by the user. I've gotten it to execute a single shell command, but the scripts provided will be more complicated than that.

Googling got me as far as the following code snippet:

FILE *pipe;
char str[100];

// The python line here is just an example, this is *not* about executing
// this particular line.
pipe = popen("python -c \"print 5 * 6\" 2>&1", "r");

fgets(str, 100, pipe);
cout << "Output: " << str << endl;

pclose(pipe)

So that this point str has 30 in it. So far so good. But what if the command has carriage returns in it, as a shell script file would, something like the following:

pipe = popen("python -c \"print 5 * 6\"\nbc <<< 5 + 6 2>&1", "r");

With this my goal is that str eventually have 30\n11.

To put another way, assume I have a file with the following contents:

python -c "print 5 * 6"
bc <<< 5 + 6

The argument I'm sending to popen above is the string representation of that file. I want to, from within C++, send that string (or something similar) to bash and have it execute exactly as if I were in the shell and sourced it with . file.sh, but setting the str variable to what I would see in the shell if it were executed there, in this case, 30\n11.

Yes, I could write this to a file and work it that way, but that seems like it should be unnecessary.

I wouldn't think this was a new problem, so either I'm thinking about it in a completely wrong way or there's a library that I simply don't know about that already does this.

7
  • Well, it appears, according to someone, that I've asked a poor question. Feedback on how so would have been helpful. Commented Aug 2, 2014 at 0:38
  • Well, it is really hard to see what you are actually asking. Especially your second example makes no sense. It's not clear what is supposed to happen when you pass bc <<< 5+6 into python. Are you missing a \" at that point? Commented Aug 2, 2014 at 0:40
  • You can separate multiple commands with ;, I believe. Commented Aug 2, 2014 at 0:40
  • what about something like python -c "exec(\"import sys\\nfor r in range(10): print 'test'\")"? There is something that may help here: stackoverflow.com/q/2043453/3093378 Commented Aug 2, 2014 at 0:42
  • Another thing I don't understand: You call fgets only once, but expect more than one line to be in str as a result? Commented Aug 2, 2014 at 0:50

1 Answer 1

1

use bash -c.

#include <stdio.h>

int main()
{
    FILE *pipe = popen("bash -c \"echo asdf\necho 1234\" ", "r");
    char ch;
    while ((ch = fgetc(pipe)) != EOF)
        putchar(ch);
}

Output:

asdf
1234

(I've test on cygwin)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.