Home > Software design >  perl - return value from python
perl - return value from python

Time:07-26

I'm running a perl script that runs a python script.

# python code = run_me.py

def main():
    return 123;

if __name__ == '__main__':
    main()

and the perl code:

# perl code
my $ret = // What should I write here?
print "ret = $ret" # should print "ret = 123"

system("run_me.py") --> returns exit code (in this case 0)

`run_me.py` --> returns the stdout (in this case empty string)

How do I get the 123 back to the perl without opening sockets or files? Is that possible?

Thanks!

CodePudding user response:

The Python program is written incorrectly for what you want to do with it. You want the 123 to be communicated from the Python process into some other process. But Python's return does not perform interprocess communication. (Hence ikegami's suggestion of sys.exit(), which is an interprocess communication mechanism.) The best solution is to fix the Python script:

        # run_me.py
        if __name__ == '__main__':
            print(main())

Then some other process, such as one running Perl, can read the output of the main function from a pipe:

        # perl
        my $result = qx{ run_me.py };

If for some reason it is impossible for you to modify the Python program, you can still get it to do what you want, but it will be a hack, because it has to work around the misdesign of the original Python program. In Perl, try:

        # perl
        my $result = qx{ python -c 'import run_me; print(run_me.main())' };

I would prefer to use a pipe rather than exit because it is more general and less subject to obscure limitations. But if you did really want to use exit the same hack would work for exfiltrating the 123 from the Python process:

        # perl
        system "python -c 'import run_me; exit(run_me.main())' ";
        my $result = $? >> 8 ;

CodePudding user response:

Your Python program doesn't currently output anything.[1]

It looks like you are trying to set the exit code. To set the exit code, use sys.exit.

import sys

def main():
    sys.exit(123)

if __name__ == '__main__':
    main()

or

import sys

def main():
    return 123

if __name__ == '__main__':
    sys.exit(main())

  1. Technically, you could say it outputs an empty stream to stdout, an empty stream to stderr, and an exit code of zero. But it definitely doesn't output 123 in any way.
  • Related