0

Sorry about the title it may not be clear. Here is the complete explanation of my doubt. I am writing the below shell script and expecting the mentioned output.

#!/bin/bash
python3
print("Hello World")
exit()
echo "The execution is completed"

The output what i am expecting is, it should enter the python3 interpreter and execute the print and exit() commands and after executing the exit() command as the interpreter exits if we do it manually and then execute the echo command.But it is not working that way, after executing python3 it is entering the python3 interpreter but not executing the print and exit().

>>>

It is entering the python3 correctly and then stops there till i manually exit the python interpreter.

What changes should i make in order to get my expected output.

  1. The follow up question: Is it possible to get the output Hello world or any other output that is generated in the python interpreter to bash environment and use it in the bash script. 2.And method which you specify to run the python commands will that work for other tools as well?
6
  • 3
    Related: Running Multiple Line Commands with Python. Note that print "Hello World" is not valid python3 – steeldriver Sep 18 '20 at 19:29
  • yeah thanks that's my typing mistake. – Rakesh Nara 10 Sep 18 '20 at 19:34
  • Maybe this is an XY problem? Can you not change your shebang line from #!/bin/bash to #/usr/bin/env python3 and fill the file with regular python code? – iruvar Sep 18 '20 at 20:07
  • no i want to run other other bash commands as well, my main task over here is to enter into python execute few things and exit python and continue working with bash from there on. – Rakesh Nara 10 Sep 19 '20 at 10:36
  • Can't you simply do python3 -c 'print("Hello World")'? – Arkadiusz Drabczyk Sep 19 '20 at 14:56
1
#!/bin/bash
python3
print("Hello World")
exit()
echo "The execution is completed"

Scripts work differently from typing commands directly in a terminal, ie. what you want to do won't work this easily.

The #!/bin/bash line tells the kernel that the program it's trying to start is a script that need to be run with /bin/bash. So when you run ./scriptname the kernel instead runs /bin/bash ./scriptname and bash will read commands from scriptname instead of standard input (the terminal).

When bash gets to the python line it will start the Python interpreter and kindly wait for it exit before continuing to the next line. When Python starts it does the same thing it would when you type python in the terminal, it will start the interactive interpreter.

Python is unaware that you want to run commands from a script file, and you also can't tell it to skip a few lines.
When Python exits, bash will continue from the next line quit() which is a syntax error, you also can't tell Bash to skip a few lines after python.

There are three ways to get Python to run commands:

  1. Have bash write commands to the input of python via a heredoc (*1). Python can't read user input from the terminal if you do this.
  2. Use the -c option to supply a short list of commands. This is only suitable for extremely short programs that also don't need to use any quotes (for strings). Multiple commands can be separated with semicolons.
  3. Have a separate Python script, this requires a second file. If you understand the security risks associated with temporary files (*2), you can make bash create the file for you if you wish. Just don't create the files in /tmp and you should be fine.

The follow up question: Is it possible to get the output Hello world or any other output that is generated in the python interpreter to bash environment and use it in the bash script.

You can use command substitution using $( and ), please use these inside double quoted strings. You can even nest double quoted strings on the inside:

test="$(python -c "import sys; print(sys.version)")"
echo "Python has finished"
echo "test = $test"

And method which you specify to run the python commands will that work for other tools as well?

All three methods listed above will work for many other scripting languages too.


*1 Heredoc example

read -p "How many numbers: " n
python <<END
for i in range($n):
    print(i)
print("Literal dollar sign \$")
END

The <<END syntax makes the shell (bash) read all lines until it reads the word END. Note that END must be at the beginning of the line.

This way you don't need to escape quotes. The shell will still interpret dollar signs, so you can use variables. If you want an actual dollar sign you need to escape it like this \$.


*2 Example of the dangers of temp files. DO NOT USE THIS CODE

cat >/tmp/python-script <<END
for i in range(10):
    print(i)
END
python /tmp/python-script

If someone else creates /tmp/python-script first, this shell script won't even stop if it fails to overwrite the file. A malicious user on the system could make a harmful Python script which will run instead of the intended script.

This is not the only thing that can go wrong.

There are ways to do this safely, but the simplest way would be to create the files in the current working directory or in a dedicated directory in the home directory.

cat >dopythonstuff <<END
...
END
python dopythonstuff
rm dopythonstuff
2
  • Thankyou Oskar :). You wrote there will be security issues when having multiple scripts(python{a temporary one} and bash) can you specify the security issues which you meant? – Rakesh Nara 10 Sep 22 '20 at 18:38
  • 1
    The (potential) security issue is with using a temporary file. Anyone can (usually) create files in /tmp. If the temporary file is created in there and the name is deterministic, someone else could create a symlink to cause the script to overwrite a file or create a file that someone else can modify which the script will then execute. – Oskar Skog Sep 23 '20 at 14:53
0

Use Python to launch bash script and pass variable to bash script:

piping python variable value to bash script (inside python script)

There are 62 answers on this Stack Overflow question of how to call a shell command from a Python script:

https://stackoverflow.com/questions/89228/how-to-call-an-external-command

Python cannot exit and then call a shell command. You must call the shell command before you exit the Python script.

https://www.geeksforgeeks.org/python-exit-commands-quit-exit-sys-exit-and-os-_exit/

This article under the link above covers how to exit Python using various commands:

The functions quit(), exit(), sys.exit() and os._exit() have almost same functionality as they raise the SystemExit exception by which the Python interpreter exits and no stack traceback is printed. We can catch the exception to intercept early exits and perform cleanup activities; if uncaught, the interpreter exits as usual.

The article concludes:

Among above four exit functions, sys.exit() is preferred mostly, because the exit() and quit() functions cannot be used in production code while os._exit() is for special cases only when immediate exit is required.

You can use sys.exit("Exit message here") to exit the Python script and write the exit message to the console which would then return to the shell prompt.

6
  • Thanks for the answer System Theory, if we have one or two lines of python code or bash script to get executed we can use "Python -c "(command to execute python commands form normal shell) or "subprocess.run(some command)" to run shell commands from python. but i have many lines of python code to execute in between and shell commands which are to execited before and after executing python code. The main intention of this question is to know how to switch between python(or any other tool environments like metasploit) back and forth to get a task done. – Rakesh Nara 10 Sep 19 '20 at 10:47
  • Run the shell from inside python and there is no need to switch back and forth. Do some keyword searches and look for answers on Stack Overflow with patterns similar to your use case. – SystemTheory Sep 19 '20 at 13:22
  • 1
    Python libraries may also be used to perform system commands which avoid the need to call shell commands depending on your use case. If you want to launch shell scripts from python, and launch python scripts from the shell, then do a keyword search on each question, and there will be answers posted most likely on Stack Overflow or software blogs. Good luck. – SystemTheory Sep 19 '20 at 13:31
  • 1
    It appears to me that the questioner wants to do the opposite, ie. run Python code from the shell. – Oskar Skog Sep 19 '20 at 16:02
  • 1
    If the program flow for task execution is sequential then you can call a sequence of bash scripts and python scripts providing you can pass variables from python to bash and from bash to python as necessary. You can have bash or python read files with variables stored. Asynchronous tasks might require you to code a task management solution of find a task management package that works with bash and python. – SystemTheory Sep 19 '20 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.