0

I have a problem with running C++ in my Python programm. I built a Tkinter programm, to get file with c++ code and input file, so that my programm will generate .out file with output. Using subprocess library I managed to compile C++ using:

subprocess.run(['g++', '-o', 'CodeChecker', self.source_code_file_name])*

But next I would like to run my exec file with input stored in input_text variable. Please tell me, why

result = subprocess.run(['./CodeChecker', '<', 'test.in'], capture_output=True, text=True)

is not working.

I tried different variations, but none of it worked.

EDIT: I have a button that calls run_code function.

  • self.source_code_file_name contains my c++ source code
  • self.input_file is .in type and contains input

Code:

def run_code(self):
        try:
            os.chdir(self.path) # change working category
            subprocess.run(['g++', '-o', 'CodeChecker', self.source_code_file_name])
            result = subprocess.run('./CodeChecker < test.in', capture_output=True, text=True, shell=True)
            print(result.stdout)
        except: 
            # error
           print("error")

Above code works, but I want to replace test.in with variable self.input_file

2 Answers2

1

Redirection is a shell feature. You want

result = subprocess.run('./CodeChecker < test.in',
    capture_output=True, text=True,
    shell=True)

or, much better, avoid the need for shell=True;

with open('test.in', 'r') as inputfile:
    result = subprocess.run(['./CodeChecker'],
        stdin=inputfile,
        capture_output=True, text=True,
        check=True)

Notice also the addition of check=True; this obviously presupposes that CodeChecker returns a correct exit code, and that you want to trap any errors.

If you wanted to receive the input from a Python variable,

result = subprocess.run(['./CodeChecker'],
    capture_output=True, text=True,
    input=your_string_of_input_data,
    check=True)
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • It worked... WOW! Thanks a lot. I spent couple of hours for it... – piotr lezanski Apr 24 '23 at 09:32
  • One more thing, how should I change your first solution to get input from the variable, not fixed file? I tried sth like: result = subprocess.run('./CodeChecker <', stdin=self.input_file, capture_output=True, text=True, shell=True) Btw second solution gives me strange output... – piotr lezanski Apr 24 '23 at 09:39
  • Sorry, there was a typo in the example. Fixed that and added a final example showing how to use the `input=` keyword argument. – tripleee Apr 24 '23 at 10:00
  • Or do you mean `subprocess.run(..., stdin=self.input_file)` to read the input from an already-open file handle? – tripleee Apr 24 '23 at 10:01
  • Third example is working exactly how I intented! All good. Thanks – piotr lezanski Apr 24 '23 at 10:10
0

What you're trying is to use a shell construct, the file redirection, <, as an argument to a program. That doesn't work; you're not using a shell, you're just running an executable.

If you want to redirect a file to the input of the program you run, you'll need to set the right parameters of the Popen constructor as documented in the python documentation.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94