Can someone explain how this bash script works? The part I don't understand is """:"
, what does this syntax mean in bash?
#!/bin/sh
""":"
echo called by bash
exec python $0 ${1+"$@"}
"""
import sys
print 'called by python, args:',sys.argv[1:]
test running result:
$ ./callself.sh xx
called by bash
called by python, args: ['xx']
$ ./callself.sh
called by bash
called by python, args: []
That's clever! In Bash, the """:"
will be expanded into only :
, which is the empty command (it doesn't do anything). So, the next few lines will be executed, leading to exec
. At that point, Bash ceases to exist, and the file is re-read by Python (its name is $0
), and the original arguments are forwarded.
The ${1+"$@"}
means: If $1
is defined, pass as arguments "$@"
, which are the original Bash script arguments. If $1
is not defined, meaning Bash had no arguments, the result is empty, so nothing else is passed, not even the empty string.
In Python, the """
starts a multi-line string, which includes the Bash commands, and extends up to the closing """
. So Python will jump right below.
This is an example for polyglot, where you write multiple programing languages in a file and still make it valid.
How is it valid in python
""":"
echo called by bash
exec python $0 ${1+"$@"}
"""
This is a multiline docstring in python so python completely ignores it till the import
line
How is it valid in bash
""":"
echo called by bash
exec python $0 ${1+"$@"}
The exec
calls the same script using python interpreter and exits the script. So it will not execute the remaining syntactically wrong python statements.
What is the purpose of the : (colon) GNU Bash builtin?
Also, once exec is called, the rest of the code is not executed because exec replaces the shell with the program, in this case the python process. (http://wiki.bash-hackers.org/commands/builtin/exec)