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?
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 here\n']
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!
main function for CPython, remember, python is written in the c language.
python script inputreally work if you didn't usesys.argv[1]as the input?scriptisprint(input()). Doesecho 'foobar' | python scriptjust print the output, instead of ask you for the input? And, doespython script 'foobar'also print thefoobar, and didn't run theinput()? Also tryprint(__import__('sys').argv[1]), and check what the output is.