About a couple lines of code in Repo script

19 views
Skip to first unread message

Nevo

unread,
Sep 24, 2009, 4:17:34 AM9/24/09
to Repo and Gerrit Discussion
hi,
I've currently read the implementation of Repo script and trying to
customize it to my own needs ,and found the following lines :
+++++++++++++++++++++++++++++++++
magic='--calling-python-from-/bin/sh--'
"""exec" python -E "$0" "$@" """#$magic"
if __name__ == '__main__':
import sys
if sys.argv[-1] == '#%s' % magic:
del sys.argv[-1]
del magic
++++++++++++++++++++++++++++++++++
Now I understand that the code here is invoke the python interpreter
to execute the following Python code, but I cannot quite figure out
why use three double quote before exec , in other word , I cannot
quite understand
"""exec" python -E "$0" "$@" """#$magic"
My only clue is """ represents null arguments from Bash manual .
I knew this was actually not a Repo implementation specific problem ,
but I cannot search any other similar stuffs . So can someone help
explain why use so many double quotes here ? Thanks
Btw, I tried various other forms similar to this ,none of them
worked ....

Nevo

Shawn Pearce

unread,
Sep 24, 2009, 10:15:21 AM9/24/09
to repo-d...@googlegroups.com
On Thu, Sep 24, 2009 at 01:17, Nevo <sakur....@gmail.com> wrote:
>   I've currently read the implementation of Repo script and trying to
> customize it to my own needs ,and found the following lines :
> +++++++++++++++++++++++++++++++++
> magic='--calling-python-from-/bin/sh--'
> """exec" python -E "$0" "$@" """#$magic"
> if __name__ == '__main__':
>  import sys
>  if sys.argv[-1] == '#%s' % magic:
>    del sys.argv[-1]
> del magic
> ++++++++++++++++++++++++++++++++++
>  Now I understand that the code here is invoke the python interpreter
> to execute the following Python code, but I cannot quite figure out
> why  use three double quote before exec , in other word , I cannot
> quite understand
>   """exec" python -E "$0" "$@" """#$magic"

"""foo""" (text inside of triple quotes) is often treated as a comment
in Python. So the entire line up until the # is treated as a comment
by Python and is ignored when Python reads the script file. Since #
until LF is also a comment in Python, the remainder of the line is
also ignored by Python, so the entire line is ignored by Python.

"" in Bourne shell is an empty string. So the first "" in """ at the
start of the line expands to an empty string, which is then
concatenated with the next double quoted string, "exec". Since ""
plus "exec" is still "exec", Bourne reads this as though it had just
said exec right there.

At the end of the line again the first "" in """ is read as an empty
string, which is then concatenated with "#$magic". The shell expands
$magic to the value defined on the prior line, effectively adding this
to the argument vector given to Python when it execs Python. So in
the end this line looks to the Bourne shell as though it were:

exec python -E "$0" "$@" "#--calling-python-from-/bin/sh--"

Other scripting languages like Perl and Tcl have similar voodoo used
to make a script executable by both a Bourne shell and also by the
real language engine. Perl needs a less obtuse trick, IIRC its as
simple as:

#!/bin/sh
exec 'perl' "$@"
if 0;

and Tcl can use:

#!/bin/sh
# Tcl ignores the next line -*- tcl -*- \
exec tcl "$@"

Python proved much more difficult to get this to work. So the code
snippet is a bit more complex.

Nevo

unread,
Sep 24, 2009, 11:25:58 AM9/24/09
to Repo and Gerrit Discussion
hi, Shawn:
Thank you very much. Your explain is quite clear and helpful . Repo
is a great tool to manage so many projects. I hope I will be able to
use this tool plus Gerrit to manage our projects as well. Thanks :)

Nevo

On Sep 24, 10:15 pm, Shawn Pearce <s...@google.com> wrote:
Reply all
Reply to author
Forward
0 new messages