Running a python script under Linux

Discussion in 'Python' started by Andrew Robinson, Dec 13, 2012.

  1. On 12/13/2012 06:45 PM, Steven D'Aprano wrote:
    > I understand this is not exactly a Python question, but it may be of
    > interest to other Python programmers, so I'm asking it here instead of a
    > more generic Linux group.
    >
    > I have a Centos system which uses Python 2.4 as the system Python, so I
    > set an alias for my personal use:
    >
    > [steve@ando ~]$ which python
    > alias python='python2.7'
    > /usr/local/bin/python2.7
    >
    >
    > When I call "python some_script.py" from the command line, it runs under
    > Python 2.7 as I expected. So I give the script a hash-bang line:
    >
    > #!/usr/bin/env python
    >
    > and run the script directly, but instead of getting Python 2.7, it runs
    > under Python 2.4 and gives me system errors.
    >
    > When I run env directly, it ignores my alias:
    >
    > steve@ando ~]$ /usr/bin/env python -V
    > Python 2.4.3
    >
    >
    > What am I doing wrong?
    >


    After seeing the lecture on Bad Ideas ... this might backfire on me.... :)

    But ... if you really want to make the alias show up in all bash shells,
    you can put it in your ~/.bashrc file which is executed every time a
    shell is created.
    alias python='python2.7'

    However, alias expansions do not work in non-interactive shells -- so I
    don't think it will launch with the #!/bin/env technique.

    OTOH -- Shell functions DO operate in non-interactive mode, so you could
    add something like:

    function python() {
    python3 # whichever version of python you want as default
    }
    # eof of function example to add to ~/.bashrc

    OR............
    In a bash shell, you can also do:

    function python {
    python3 # or 2.7 ...
    }
    export -f python

    And that would give the same effect as an alias, but funtions can be
    exported to child processes.

    It's your system, and we're adults here -- screw it up however you want to.
    Cheers!








    --
    --Jesus Christ is Lord.
     
    Andrew Robinson, Dec 13, 2012
    #1
    1. Advertising

  2. On 12/13/2012 06:45 PM, Steven D'Aprano wrote:
    > What am I doing wrong?
    >
    >

    By the way, I didn't include command line parameters as part of the
    function definition, so you might want to add them to insure it acts
    like a generic alias.

    Also, (alternately), you could define a generic python shell
    script/import with the duty of checking for a compatible python version;
    and if the wrong one is executing -- it could then import the shell
    command execution function, and *fork* the correct version of python on
    the script; then it could exit.

    .... or whatever.... ;)
     
    Andrew Robinson, Dec 14, 2012
    #2
    1. Advertising

  3. I understand this is not exactly a Python question, but it may be of
    interest to other Python programmers, so I'm asking it here instead of a
    more generic Linux group.

    I have a Centos system which uses Python 2.4 as the system Python, so I
    set an alias for my personal use:

    [steve@ando ~]$ which python
    alias python='python2.7'
    /usr/local/bin/python2.7


    When I call "python some_script.py" from the command line, it runs under
    Python 2.7 as I expected. So I give the script a hash-bang line:

    #!/usr/bin/env python

    and run the script directly, but instead of getting Python 2.7, it runs
    under Python 2.4 and gives me system errors.

    When I run env directly, it ignores my alias:

    steve@ando ~]$ /usr/bin/env python -V
    Python 2.4.3


    What am I doing wrong?


    --
    Steven
     
    Steven D'Aprano, Dec 14, 2012
    #3
  4. On 14Dec2012 02:45, Steven D'Aprano <> wrote:
    | I understand this is not exactly a Python question, but it may be of
    | interest to other Python programmers, so I'm asking it here instead of a
    | more generic Linux group.
    |
    | I have a Centos system which uses Python 2.4 as the system Python, so I
    | set an alias for my personal use:
    |
    | [steve@ando ~]$ which python
    | alias python='python2.7'
    | /usr/local/bin/python2.7
    |
    |
    | When I call "python some_script.py" from the command line, it runs under
    | Python 2.7 as I expected. So I give the script a hash-bang line:
    |
    | #!/usr/bin/env python
    |
    | and run the script directly, but instead of getting Python 2.7, it runs
    | under Python 2.4 and gives me system errors.
    |
    | When I run env directly, it ignores my alias:
    |
    | steve@ando ~]$ /usr/bin/env python -V
    | Python 2.4.3
    |
    |
    | What am I doing wrong?

    You're assuming aliases are exported. They are not. (I've seen ksh
    present exportable aliases, but IMO it is a bad idea anyway.)

    You're (slightly) better off putting a python symlink in /usr/local/bin, but
    that may break arbitrary other things (as, indeed, would your #! incantation
    were it effective). Also a bad idea though.

    Regarding aliases, I would make a "py27" alias for my personal typing
    convenience perhaps, but _not_ try to make the command "python" run
    anything but the system default python (24, as you say).

    When I need a particular minimum revision of python I use one of my
    "py25+", "py26+", "py27+", "py30+" etc wrapper scripts. Code for "py25+"
    here:

    https://bitbucket.org/cameron_simpson/css/src/tip/bin/py25

    This has the advantages of not conflicting with a system name like
    "python" and also is usable with your #! incantation, which requires an
    executable file after "env".

    Cheers,
    --

    Carpe Datum - John Sloan <>
     
    Cameron Simpson, Dec 14, 2012
    #4
  5. Steven D'Aprano writes:

    > I have a Centos system which uses Python 2.4 as the system Python, so I
    > set an alias for my personal use:
    >
    > [steve@ando ~]$ which python
    > alias python='python2.7'
    > /usr/local/bin/python2.7
    >
    >
    > When I call "python some_script.py" from the command line, it runs under
    > Python 2.7 as I expected. So I give the script a hash-bang line:
    >
    > #!/usr/bin/env python
    >
    > and run the script directly, but instead of getting Python 2.7, it runs
    > under Python 2.4 and gives me system errors.
    >
    > When I run env directly, it ignores my alias:
    >
    > steve@ando ~]$ /usr/bin/env python -V
    > Python 2.4.3


    The alias is known only to the shell for which it is defined. The
    shell does nothing with it when it occurs in an argument position. So
    env receives just the six-letter string "python" which it resolves as
    a program name by walking the file system along your PATH until it
    finds the program.

    Why not just set your PATH so that the python that is python2.7 is
    found first. If this breaks something, your alias would also have
    broken that something if aliases worked the way you wanted. Try.
     
    Jussi Piitulainen, Dec 14, 2012
    #5
  6. Andrew Robinson

    Hans Mulder Guest

    On 14/12/12 03:45:18, Steven D'Aprano wrote:
    > I understand this is not exactly a Python question, but it may be of
    > interest to other Python programmers, so I'm asking it here instead of a
    > more generic Linux group.
    >
    > I have a Centos system which uses Python 2.4 as the system Python, so I
    > set an alias for my personal use:
    >
    > [steve@ando ~]$ which python
    > alias python='python2.7'
    > /usr/local/bin/python2.7
    >
    >
    > When I call "python some_script.py" from the command line, it runs under
    > Python 2.7 as I expected. So I give the script a hash-bang line:
    >
    > #!/usr/bin/env python
    >
    > and run the script directly, but instead of getting Python 2.7, it runs
    > under Python 2.4 and gives me system errors.
    >
    > When I run env directly, it ignores my alias:
    >
    > steve@ando ~]$ /usr/bin/env python -V
    > Python 2.4.3
    >
    >
    > What am I doing wrong?


    You're using an alias. Aliases are not normally exported, and
    even if they are (e.g. ksh can be configure to export aliases),
    env doesn't recognize them.

    What would work, is changing your PATH environment variable
    so that the first python on your PATH is the one you want,
    or a symlink pointing to it.

    The Pythonic way to get what you want, is to be explicit:

    #!/usr/local/bin/python2.7 -V

    If you do that, it will even work in situations where you
    can't control PATH, such as CGI scripts and cron jobs.

    There are situations where using #!/usr/bin/env makes sense,
    but yours isn't one of them.

    Hope this helps,

    -- HansM
     
    Hans Mulder, Dec 14, 2012
    #6
  7. On Fri, 14 Dec 2012 14:18:28 +0100
    Hans Mulder <> wrote:
    > The Pythonic way to get what you want, is to be explicit:
    >
    > #!/usr/local/bin/python2.7 -V
    >
    > If you do that, it will even work in situations where you
    > can't control PATH, such as CGI scripts and cron jobs.


    As long as you only run on one system that's OK. That won't work on
    NetBSD or Linux[1] for example.

    > There are situations where using #!/usr/bin/env makes sense,
    > but yours isn't one of them.


    #! /usr/bin/env python2.7

    [1]: Well, Ubuntu anyway. I don't know about the others.

    --
    D'Arcy J.M. Cain <> | Democracy is three wolves
    http://www.druid.net/darcy/ | and a sheep voting on
    +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
    IM:
     
    D'Arcy J.M. Cain, Dec 14, 2012
    #7
  8. Andrew Robinson

    Hans Mulder Guest

    On 14/12/12 14:38:25, D'Arcy J.M. Cain wrote:
    > On Fri, 14 Dec 2012 14:18:28 +0100
    > Hans Mulder <> wrote:
    >> The Pythonic way to get what you want, is to be explicit:
    >>
    >> #!/usr/local/bin/python2.7 -V
    >>
    >> If you do that, it will even work in situations where you
    >> can't control PATH, such as CGI scripts and cron jobs.

    >
    > As long as you only run on one system that's OK.


    As I understand it, the OP has a single system where the
    system Python is CPython 2.4, and he has install 2.7 in
    /usr/local/bin.

    > That won't work on NetBSD or Linux[1] for example.


    I would expect it to work, as long as /usr/local/bin/python2.7
    exists and is a binary executable for the right architecture.

    Why wouldn't it work?

    It doesn't exceed the 32-character limit and it contains
    only one option. What other pitfalls are there?

    >> There are situations where using #!/usr/bin/env makes sense,
    >> but yours isn't one of them.

    >
    > #! /usr/bin/env python2.7


    On my box, that line might find a python2.7 in the
    currently active virtualenv, which may have the wrong
    set of third-party modules in its site-packages.

    When I write a script that is meant to be used as a
    utility, independent of which virtualenv is currently
    active, then I'll make sure that its #! line points
    at the Python2.7 install I used to test it.

    > [1]: Well, Ubuntu anyway. I don't know about the others.



    Just curious,

    -- HansM
     
    Hans Mulder, Dec 14, 2012
    #8
  9. On 12/13/2012 07:45 PM, Steven D'Aprano wrote:
    > When I call "python some_script.py" from the command line, it runs under
    > Python 2.7 as I expected. So I give the script a hash-bang line:
    >
    > #!/usr/bin/env python
    >
    > and run the script directly, but instead of getting Python 2.7, it runs
    > under Python 2.4 and gives me system errors.
    >
    > When I run env directly, it ignores my alias:
    >
    > steve@ando ~]$ /usr/bin/env python -V
    > Python 2.4.3
    >
    >
    > What am I doing wrong?


    Hash-bang isn't a shell function; it's a kernel function. There's no
    reason why a shell setting (alias) would be known to the kernel.
    Different shells have different ideas about aliases anyway. And the
    program that the she-bang tells the kernel to run is /usr/bin/env, again
    something that doesn't have anything to do with the shell. The only
    thing the shell can communicate to the env program is the environment,
    including the PATH variable, which env searches.

    The reason it works this way is that the shell is simply another program
    that can be replaced. One could make a shell based on python, and it
    might replace the bash "alias" command with a completely different
    mechanism.

    When I was first exposed to Linux, it took me a long time to understand
    and appreciate how basic commands like ls and env are not part of shell
    at all, unlike my experience with the DOS and Windows command.com and
    cmd.exe shells. At first I found this archaic and frustrating. But
    later I realized the great power of doing things this way. If I didn't
    like the way ls listed things, I could change it; replace ls easily. I
    remember seeing TSRs (remember them!) that would hook into command.com
    and patch it to add or alter command.com commands. The Unix way was
    definitely cleaner.
     
    Michael Torrie, Dec 14, 2012
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hshdude
    Replies:
    12
    Views:
    1,113
    Dimitri Maziuk
    Nov 4, 2004
  2. bronby
    Replies:
    1
    Views:
    674
    Andrew Thompson
    Jul 15, 2005
  3. xunil
    Replies:
    2
    Views:
    29,569
    Ryan Paul
    May 17, 2004
  4. Luke Kenneth Casson Leighton
    Replies:
    0
    Views:
    389
    Luke Kenneth Casson Leighton
    Jan 15, 2009
  5. Ezra Zygmuntowicz
    Replies:
    4
    Views:
    144
    Ezra Zygmuntowicz
    Jul 12, 2006
Loading...

Share This Page