To run a set of Python commands from a
bash script, you must give the Python interpreter the commands to run, either from a file (Python script) that you create in the script, as in
# Create script as "script.py"
cat >script.py <<'END_SCRIPT'
# Run script.py
(this creates a new file called
script.py or overwrites that file if it already exists, and then instructs Python to run it; it is then deleted)
... or directly via some form of redirection, for example a here-document:
python - <<'END_SCRIPT'
What this does is running
python - which instructs the Python interpreter to read the script from standard input. The shell then sends the text of the Python script (delimited by
END_SCRIPT in the shell script) to the Python process' standard input stream.
Note that the two bits of code above are subtly different in that the second script's Python process has its standard input connected to the script that it's reading, while the first script's Python process is free to read data other than the script from standard input. This matters if your Python code reads from standard input.
Python can also take a set of commands from the command line directly with its
python -c 'print("TESTPRINT")'
What you can't do is to "switch to Python" in the middle of a
The commands in a script is executed by
bash one after the other, and while a command is executing, the script itself waits for it to terminate (if it's not a background job).
This means that your original script would start Python in interactive mode, temporarily suspending the execution of the
bash script until the Python process terminates. The script would then try to execute
print("TESTPRINT") as a shell command.
It's a similar issue with using
ssh like this in a script:
(which may possibly be similar to what you say you tried a few years ago).
This would not connect to the remote system and run the
ls commands there. It would start an interactive shell on the remote system, and once that shell has terminated (giving control back to the script),
ls would be run locally.
Instead, to execute the commands on a remote machine, use
ssh user@server "cd /tmp; ls"
(This is a lame example, but you may get the point).
The below example shows how you may actually do what you propose. It comes with several warning label and caveats though, and you should never ever write code like this (because it's obfuscated and therefore unmaintainable and, dare I say it, downright bad).
$ sh -s <script.sh
What happens here is that the script is being run by
sh -s. The
-s option to
sh (and to
bash) tells the shell to execute the shell script arriving over the standard input stream.
The script then starts
python -, which tells Python to run whatever comes in over the standard input stream. The next thing on that stream, since it's inherited from
sh -s by Python (and therefore connected to our script text file), is the Python command
The Python interpreter would then continue reading and executing commands from the script file until it runs out or executes the Python command