Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • outputting a command to the terminal?

    17 answers - 1248 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Here's my new project: I want to write a little script that I can type
    at the terminal like this:
    $ scriptname package1 [package2, ]
    where scriptname is my module name and any subsequent arguments are the
    names of Linux packages to install. Running the script as above will
    create this line:
    sudo aptitude install package1 package2
    It will run that line at the terminal so the package(s) will be installed.
    Now, the extra functionality I want to add (otherwise I would just
    install them normally!) is to save the package names to a text file so I
    can now the names of programs I've manually installed, if I ever want to
    check the list or remove packages.
    So creating the proper bash command (sudo aptitude install ) is easy,
    and writing the names to a file is easy. But I have two questions:
    1. First of all, does Linux keep track of the packages you manually
    install? If so, then I won't have to do this at all.
    2. Assuming I write this, how do output the bash command to the
    terminal? Is there a particular module that Python uses to interact with
    the terminal window that I can use to send the install command to the
    terminal?
    Thanks.
  • No.1 | | 1526 bytes | |

    John Salerno schrieb:
    Here's my new project: I want to write a little script that I can type
    at the terminal like this:

    $ scriptname package1 [package2, ]

    where scriptname is my module name and any subsequent arguments are the
    names of Linux packages to install. Running the script as above will
    create this line:

    sudo aptitude install package1 package2

    It will run that line at the terminal so the package(s) will be installed.

    Now, the extra functionality I want to add (otherwise I would just
    install them normally!) is to save the package names to a text file so I
    can now the names of programs I've manually installed, if I ever want to
    check the list or remove packages.

    So creating the proper bash command (sudo aptitude install ) is easy,
    and writing the names to a file is easy. But I have two questions:

    1. First of all, does Linux keep track of the packages you manually
    install? If so, then I won't have to do this at all.

    2. Assuming I write this, how do output the bash command to the
    terminal? Is there a particular module that Python uses to interact with
    the terminal window that I can use to send the install command to the
    terminal?

    You don't put a command to the terminal. The shell executes commands.
    But it is mainly just a program itself - it can spawn subprocesses and
    make these execute the actual commands. so - the module you need is most
    probably subprocess.

    Diez
  • No.2 | | 1571 bytes | |

    John Salerno wrote:
    1. First of all, does Linux keep track of the packages you manually
    install? If so, then I won't have to do this at all.

    I assume you're using a Debian-based distro with aptitude as the front
    end. In which case, all dpkg operations should be logged in
    /var/log/dpkg.log

    Generally, after the initial installation, all subsequent operations are
    either updates of existing packages or packages you installed manually.
    rarely do you get new packages installed automatically as a result
    of an additional dependency from an original automatically installed
    package.

    If you know when you completed your initial installation, you can easily
    parse the log files to determine what else was installed after that.

    2. Assuming I write this, how do output the bash command to the
    terminal? Is there a particular module that Python uses to interact with
    the terminal window that I can use to send the install command to the
    terminal?

    I'm wondering about the need to "output the bash command to the
    terminal". It would probably suffice if your Python script just spawned
    an instance of the shell with the necessary command line. Take a look at
    the subprocess module.

    But this really calls for a bash script:

    #!/bin/bash
    echo $@ >/path/to/manual_install.log
    sudo aptitude install $@

    Shorter than the equivalent Python code. You could probably declare this
    as a function in your bash initialization files too, if you know how to
    do this.
  • No.3 | | 1407 bytes | |

    Yu-Xi Lim wrote:

    I assume you're using a Debian-based distro with aptitude as the front
    end. In which case, all dpkg operations should be logged in
    /var/log/dpkg.log

    Yes, I'm using Ubuntu. But I checked this log file and I'm a bit
    confused. It has a lot of listings for 5-31-06, but I didn't even
    install Linux until last Saturday. The next date after 5-31 is 8-5-06,
    and I know I installed things between last Saturday and Aug. 5.

    (But this is T, so don't worry about it.)

    I'm wondering about the need to "output the bash command to the
    terminal". It would probably suffice if your Python script just spawned
    an instance of the shell with the necessary command line. Take a look at
    the subprocess module.

    But this really calls for a bash script:

    #!/bin/bash
    echo $@ >/path/to/manual_install.log
    sudo aptitude install $@

    Shorter than the equivalent Python code. You could probably declare this
    as a function in your bash initialization files too, if you know how to
    do this.

    Hmm, interesting. I figured I could do this with a bash script, but I
    don't know bash at all and I'm trying to stick with Python. I don't
    quite understand your bash script (not familiar with the $@ syntax).

    I think I'll take a look at the subprocess module, just for fun. :)
  • No.4 | | 393 bytes | |

    John Salerno wrote:

    I think I'll take a look at the subprocess module, just for fun. :)

    and for learning too :-)

    Also, consider that some operating system commands are built into the
    shell (i.e. not run as a separate process), which makes using the
    subprocess module a bit difficult -- for more fun and learning, check
    out os.system()

    Cheers,
    John
  • No.5 | | 1194 bytes | |

    Sun, 13 Aug 2006 20:21:26 -0400, John Salerno
    <johnjsal (AT) NSPAMgmail (DOT) comdeclaimed the following in comp.lang.python:

    Yes, I'm using Ubuntu. But I checked this log file and I'm a bit
    confused. It has a lot of listings for 5-31-06, but I didn't even
    install Linux until last Saturday. The next date after 5-31 is 8-5-06,
    and I know I installed things between last Saturday and Aug. 5.

    Pardon, between when?

    August 5 was "last Saturday" if you ignore "yesterday" (well, since
    my watch says it is now Monday "day before last").

    I'd guess the "May 31" entries are those that were "snapshots" of
    the S installer date. August 5, first Saturday in the month, might be
    the first non-standard installed package.

    Hmm, interesting. I figured I could do this with a bash script, but I
    don't know bash at all and I'm trying to stick with Python. I don't
    quite understand your bash script (not familiar with the $@ syntax).

    Well, I don't do shell scripts either, but looking at the
    sample "$@" is likely the shell equivalent of Python's sys.argv -- or
    *sys.argv if passed down
  • No.6 | | 1564 bytes | |

    Dennis Lee Bieber wrote:
    Sun, 13 Aug 2006 20:21:26 -0400, John Salerno
    <johnjsal (AT) NSPAMgmail (DOT) comdeclaimed the following in comp.lang.python:

    >Yes, I'm using Ubuntu. But I checked this log file and I'm a bit
    >confused. It has a lot of listings for 5-31-06, but I didn't even
    >install Linux until last Saturday. The next date after 5-31 is 8-5-06,
    >and I know I installed things between last Saturday and Aug. 5.
    >>

    Pardon, between when?

    Wow, I can't believe how time goes. Aug. 5 *was* the first day! I knew I
    had installed it a week ago, but I was thinking it was the last Saturday
    in July, not Aug. 5 already!

    August 5 was "last Saturday" if you ignore "yesterday" (well, since
    my watch says it is now Monday "day before last").

    I'd guess the "May 31" entries are those that were "snapshots" of
    the S installer date. August 5, first Saturday in the month, might be
    the first non-standard installed package.

    >Hmm, interesting. I figured I could do this with a bash script, but I
    >don't know bash at all and I'm trying to stick with Python. I don't
    >quite understand your bash script (not familiar with the $@ syntax).
    >>

    Well, I don't do shell scripts either, but looking at the
    sample "$@" is likely the shell equivalent of Python's sys.argv -- or
    *sys.argv if passed down
  • No.7 | | 2584 bytes | |

    John Salerno wrote:
    Here's my new project: I want to write a little script that I can type
    at the terminal like this:

    $ scriptname package1 [package2, ]

    where scriptname is my module name and any subsequent arguments are the
    names of Linux packages to install. Running the script as above will
    create this line:

    sudo aptitude install package1 package2

    It will run that line at the terminal so the package(s) will be installed.

    Now, the extra functionality I want to add (otherwise I would just
    install them normally!) is to save the package names to a text file so I
    can now the names of programs I've manually installed, if I ever want to
    check the list or remove packages.

    So creating the proper bash command (sudo aptitude install ) is easy,
    and writing the names to a file is easy. But I have two questions:

    1. First of all, does Linux keep track of the packages you manually
    install? If so, then I won't have to do this at all.

    2. Assuming I write this, how do output the bash command to the
    terminal? Is there a particular module that Python uses to interact with
    the terminal window that I can use to send the install command to the
    terminal?

    I don't know the answer to the first bit here, but I think the following
    should get you most of what you want as far as the second bit is concerned:

    scriptname.py
    import argparse #
    import subprocess
    import sys

    def outputfile(filename):
    return open(filename, 'w')

    if __name__ == '__main__':
    # parse the command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('packages', metavar='package', nargs='+',
    help='one of the packages to install')
    parser.add_argument('', type=outputfile, default=sys.stdout,
    help='a file to save the package names to')
    namespace = parser.parse_args()

    # call the command
    command = ['sudo', 'aptitude', 'install'] + namespace.packages
    subprocess.call(command)

    # write the package name file
    for package_name in namespace.packages:
    namespace.save.write('%s\n' % package_name)

    $ scriptname.py -h
    usage: scriptname.py [-h] [ SAVE] package [package ]

    positional arguments:
    package one of the packages to install

    optional arguments:
    -h, show this help message and exit
    SAVE a file to save the package names to

    STeVe
  • No.8 | | 3067 bytes | |

    Steven Bethard wrote:
    John Salerno wrote:
    >Here's my new project: I want to write a little script that I can type
    >at the terminal like this:
    >>

    >$ scriptname package1 [package2, ]
    >>

    >where scriptname is my module name and any subsequent arguments are
    >the names of Linux packages to install. Running the script as above
    >will create this line:
    >>

    >sudo aptitude install package1 package2
    >>

    >It will run that line at the terminal so the package(s) will be
    >installed.
    >>

    >Now, the extra functionality I want to add (otherwise I would just
    >install them normally!) is to save the package names to a text file so
    >I can now the names of programs I've manually installed, if I ever
    >want to check the list or remove packages.
    >>

    >So creating the proper bash command (sudo aptitude install ) is
    >easy, and writing the names to a file is easy. But I have two questions:
    >>

    >1. First of all, does Linux keep track of the packages you manually
    >install? If so, then I won't have to do this at all.
    >>

    >2. Assuming I write this, how do output the bash command to the
    >terminal? Is there a particular module that Python uses to interact
    >with the terminal window that I can use to send the install command to
    >the terminal?


    I don't know the answer to the first bit here, but I think the following
    should get you most of what you want as far as the second bit is concerned:

    scriptname.py
    import argparse #
    import subprocess
    import sys

    def outputfile(filename):
    return open(filename, 'w')

    if __name__ == '__main__':
    # parse the command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('packages', metavar='package', nargs='+',
    help='one of the packages to install')
    parser.add_argument('', type=outputfile, default=sys.stdout,
    help='a file to save the package names to')
    namespace = parser.parse_args()

    # call the command
    command = ['sudo', 'aptitude', 'install'] + namespace.packages
    subprocess.call(command)

    # write the package name file
    for package_name in namespace.packages:
    namespace.save.write('%s\n' % package_name)

    $ scriptname.py -h
    usage: scriptname.py [-h] [ SAVE] package [package ]

    positional arguments:
    package one of the packages to install

    optional arguments:
    -h, show this help message and exit
    SAVE a file to save the package names to

    STeVe

    yikes! I'll have to take some time to study this! I appreciate it. :)
  • No.9 | | 244 bytes | |

    Dennis Lee Bieber wrote:
    Well, I don't do shell scripts either, but looking at the
    sample "$@" is likely the shell equivalent of Python's sys.argv -- or
    *sys.argv if passed down
    Yeah, kinda equivalent to *sys.argv[1:].
  • No.10 | | 126 bytes | |

    Steven Bethard wrote:
    import argparse #
    import subprocess
    import sys
    Why not the standard lib's optparse?
  • No.11 | | 2992 bytes | |

    John Salerno wrote:
    Steven Bethard wrote:
    >scriptname.py
    >import argparse #
    >import subprocess
    >import sys
    >>

    >def outputfile(filename):
    >return open(filename, 'w')
    >>

    >if __name__ == '__main__':
    ># parse the command line arguments
    >parser = argparse.ArgumentParser()
    >parser.add_argument('packages', metavar='package', nargs='+',
    >help='one of the packages to install')
    >parser.add_argument('', type=outputfile, default=sys.stdout,
    >help='a file to save the package names to')
    >namespace = parser.parse_args()
    >>

    ># call the command
    >command = ['sudo', 'aptitude', 'install'] + namespace.packages
    >subprocess.call(command)
    >>

    ># write the package name file
    >for package_name in namespace.packages:
    >namespace.save.write('%s\n' % package_name)
    >
    >>
    >>

    >$ scriptname.py -h
    >usage: scriptname.py [-h] [ SAVE] package [package ]
    >>

    >positional arguments:
    >package one of the packages to install
    >>

    >optional arguments:
    >-h, show this help message and exit
    >SAVE a file to save the package names to
    >


    yikes! I'll have to take some time to study this! I appreciate it. :)

    For just calling the command, the important lines are::

    command = ['sudo', 'aptitude', 'install'] + namespace.packages
    subprocess.call(command)

    where you could have probably used ``sys.argv[1:]`` instead of
    namespace.packages.

    For writing the file, as I'm sure you've already figured out, the
    important lines are::

    for package_name in namespace.packages:
    namespace.save.write('%s\n' % package_name)

    where again, if you weren't using argparse, you could have used
    ``sys.argv`` to determine the package names (namespace.packages) and the
    file to write to (namespace.save).

    The remaining lines involving the ``parser`` object are basically
    defining a command line interface in a similar way to what optparse in
    the stdlib does. Sure, you could do all of this by fiddling with
    sys.argv, but the argparse module will do all the parsing and
    conversions for you, and give your script a meaningful usage message.
    And I'm a firm believer in meaningful usage messages. =)

    STeVe

    P.S. Thank *you* for posting this. As a result, I've been convinced
    that argparse should grow a 'outfile' type, something I've been debating
    with myself about for a while now.
  • No.12 | | 305 bytes | |

    Steven Bethard wrote:

    P.S. Thank *you* for posting this. As a result, I've been convinced
    that argparse should grow a 'outfile' type, something I've been debating
    with myself about for a while now.

    Heh heh. I'm glad my ignorance can inspire those around me. ;)
  • No.13 | | 1820 bytes | |

    Yu-Xi Lim wrote:
    Steven Bethard wrote:
    >import argparse #
    >import subprocess
    >import sys


    Why not the standard lib's optparse?

    The page referenced above gives a variety of reasons, but the two most
    important things in this example are: argparse supports parsing of both
    positional and optional arguments, and argparse generates better usage
    messages.

    Since argparse supports positional arguments, I can write something like::

    parser.add_argument('packages', , nargs='+', )

    and then the arparse module will enforce that at least one positional
    argument was given. With optparse, you'd do something like:

    options, args = parser.parse_args()
    if not args:
    parser.error('wrong number of arguments')

    Basically, with optparse, anything that involves positional arguments
    has to be handled by the user.

    It's also worth pointing out the better usage messages. Notice that the
    output looked like::

    $ scriptname.py -h
    usage: scriptname.py [-h] [ SAVE] package [package ]

    positional arguments:
    package one of the packages to install

    optional arguments:
    -h, show this help message and exit
    SAVE a file to save the package names to

    With the optparse, you'd get something like::

    $ scriptname.py -h
    usage: scriptname.py [PTINS]

    options:
    -h, show this help message and exit
    SAVE a file to save the package names to

    The argparse module knows how to create a meaningful usage message
    instead of just "%prog [PTINS]", and the argparse module knows about
    positional arguments, so you can have help messages for them too.

    , enough propaganda for now. ;-)

    STeVe
  • No.14 | | 4919 bytes | |

    John Salerno wrote:
    Yu-Xi Lim wrote:

    I assume you're using a Debian-based distro with aptitude as the front
    end. In which case, all dpkg operations should be logged in
    /var/log/dpkg.log

    Yes, I'm using Ubuntu. But I checked this log file and I'm a bit
    confused. It has a lot of listings for 5-31-06, but I didn't even
    install Linux until last Saturday. The next date after 5-31 is 8-5-06,
    and I know I installed things between last Saturday and Aug. 5.

    (But this is T, so don't worry about it.)

    I'm wondering about the need to "output the bash command to the
    terminal". It would probably suffice if your Python script just spawned
    an instance of the shell with the necessary command line. Take a look at
    the subprocess module.

    But this really calls for a bash script:

    #!/bin/bash
    echo $@ >/path/to/manual_install.log
    sudo aptitude install $@
    --
    Shorter than the equivalent Python code. You could probably declare this
    as a function in your bash initialization files too, if you know how to
    do this.

    Hmm, interesting. I figured I could do this with a bash script, but I
    don't know bash at all and I'm trying to stick with Python. I don't
    quite understand your bash script (not familiar with the $@ syntax).

    I think I'll take a look at the subprocess module, just for fun. :)

    Hey John, Yu-Xi Lim's right. This is one of those (thankfully few)
    cases where bash makes more sense to use than python (at least IMH)

    To figure out about that $@, fire up your teminal and type "man bash"
    ("!man bash" in IPython) (BTW, apropos of nothing, "man bash" is one of
    my all time favorite commands ever. I always think of some comic-book
    hero/monster shouting it, "MAN BASH!!" lol. Anyway)

    So, now you're looking at the man page for bash. It's very very long
    and ubergeeky. Deep and amazing mysteries are contained (and kind of
    explained) within it. You want information on $@ so we'll use the
    search incantation to find and reveal it.

    Type "/\$@" without the quotes, then press return. (What this
    means/does: "/" is the manpage search command, it uses a regular
    expression syntax not dissimilar to python's own. "\" escapes the next
    character ("$", in this case) and we need to do that because "$" is
    regular expression syntax for "end of line". The "$@" will now match,
    um, "$@" correctly.)

    you press return, man will scroll to put the first occurance of
    "$@" at the top of your terminal and highlight it. my system it's
    this line (I narrowed my terminal so that quoted portions wouldn't wrap
    badly in this posting):

    "$@" as explained below under Special Parameters.

    So far so good, '"$@" as explained below' looks promising. Rather than
    scrolling down to find this "Special Parameters" section, let's keep
    using the search.

    Press "n" to scroll to the next occurance of our pattern "$@". my
    system this brings me to:

    separate word. That is, "$@" is equivalent to
    "$1" "$2" If the double-quoted expansion

    Ah ha! Scrolling up a few lines, we see:

    @ Expands to the positional parameters, starting
    from one. When the expansion occurs within
    double quotes, each parameter expands to a
    separate word. That is, "$@" is equivalent to
    "$1" "$2" If the double-quoted expansion
    occurs within a word, the expansion of the
    first parameter is joined with the beginning
    part of the original word, and the expansion
    of the last parameter is joined with the last
    part of the original word. When there are no
    positional parameters, "$@" and $@ expand to
    nothing (i.e., they are removed).

    Not extraordinarily enlightening, maybe, but better than sitting in the
    dark, lighting your farts. :-D (Hit "q" to exit man.)

    Basically what this means is that $@ will become the positional
    arguments that you pass to your script. You can play with this by
    writing a simple bash script like this

    #!/bin/bash
    echo $@

    and passing it args to see what it echos. (Remember to chmod +x it)

    So, long story short, Yu-Xi Lim's bash script echos your package names
    to the /path/to/manual_install.log file (">>" in bash means "append the
    output of the command to the left to the file on the right",) then it
    calls aptitude with those same package names.

    It's simple, short, and to-the-point. The equivalent python script
    would be much longer, for no appreciable gain. I write most of my tiny
    little helper scripts in python, but in this case, bash is the clear
    winnar. (And on *nix. man pages are your best friend. Plus you get to
    feel all l33t when you grok them. lol)

    Peace,
    ~Simon
  • No.15 | | 632 bytes | |

    Simon Forman wrote:

    It's simple, short, and to-the-point. The equivalent python script
    would be much longer, for no appreciable gain. I write most of my tiny
    little helper scripts in python, but in this case, bash is the clear
    winnar. (And on *nix. man pages are your best friend. Plus you get to
    feel all l33t when you grok them. lol)

    Thanks for the info! I might grudgingly decide to use a bash script in
    this case. :)

    And yes, it seems every time I ask a Linux question, everyone points me
    to a man page. Sometimes I find them difficult to decipher, but they are
    still a great help.
  • No.16 | | 1104 bytes | |

    John Salerno wrote:
    Simon Forman wrote:

    It's simple, short, and to-the-point. The equivalent python script
    would be much longer, for no appreciable gain. I write most of my tiny
    little helper scripts in python, but in this case, bash is the clear
    winnar. (And on *nix. man pages are your best friend. Plus you get to
    feel all l33t when you grok them. lol)

    Thanks for the info! I might grudgingly decide to use a bash script in
    this case. :)

    You're welcome. lol :)

    And yes, it seems every time I ask a Linux question, everyone points me
    to a man page. Sometimes I find them difficult to decipher, but they are
    still a great help.

    Yup. When I started with Linux, man pages were one of those things I
    resisted until I started actually reading them. Then I kicked
    myself for not starting sooner. :)

    Neat trick: man -k <search term>
    Shows you man pages matching your search term (I think it's the same
    thing as the "apropos" command.) It searches the command names and
    summary lines.

    Peace,
    ~Simon
  • No.17 | | 171 bytes | |

    Simon Forman wrote:
    Neat trick: man -k <search term>
    Ah, so much command line magic to learn! Maybe I should just go back to
    Windowsor maybe not. ;)

Re: outputting a command to the terminal?


max 4000 letters.
Your nickname that display:
In order to stop the spam: 7 + 6 =
QUESTION ON "Development"

EMSDN.COM