How does Python receive stdin and arguments differently?

Question:

How exactly does Python receive

echo input | python script

and

python script input

differently? I know that one comes through stdin and the other is passed as an argument, but what happens differently in the back-end?

Asked By: Rohan

||

Answers:

I’m not exactly sure what is confusing you here. stdin and command line arguments are treated as two different things.

Since you’re most likely using CPython (the C implementation of Python) the command line args are passed automatically in the argv parameter as with any other c program. The main function for CPython (located in python.c) receives them:

int main(int argc, char **argv)  // **argv <-- Your command line args
{
    wchar_t **argv_copy;   
    /* We need a second copy, as Python might modify the first one. */
    wchar_t **argv_copy2;
    /* ..rest of main omitted.. */

While the contents of the pipe are stored in stdin which you can tap into via sys.stdin.

Using a sample test.py script:

import sys

print("Argv params:n ", sys.argv)
if not sys.stdin.isatty():
    print("Stdin: n", sys.stdin.readlines())

Running this with no piping performed yields:

(Python3)jim@jim: python test.py "hello world"
Argv params:
  ['test.py', 'hello world']

While, using echo "Stdin up in here" | python test.py "hello world", we’ll get:

(Python3)jim@jim: echo "Stdin up in here" | python test.py "hello world"
Argv params:
 ['test.py', 'hello world']
Stdin: 
 ['Stdin up in heren']

Not strictly related, but an interesting note:

Additionally, I remembered that you can execute content that is stored in stdin by using the - argument for Python:

(Python3)jimm@jim: echo "print('<stdin> input')" | python -
<stdin> input

Kewl!

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.