Bash: Execute piped lines from stdin

7,821

Solution 1

Have you tried

$ python example.py | bash

It ought to work, as it's a common enough trick. For example, the monitoring tool munin has a node configurator (munin-node-configure) that tells you what plugins you can run, and then takes a --shell flag that makes it spit out a bunch of ln -s commands to link in the plugins, when piped directly to bash.

There was even once a tool for configuring something - it was over 15 years ago, I can't remember what - where you'd become root and get the config done by opening a telnet session to an autoconfigurator and send the output straight to bash, with

# telnet example.com 7001 | bash

I can't imagine doing anything like that these days.

Solution 2

I'd do this:

python example.py | while read command; do $command; done

The non-zero exit status can be worked around using ; instead of &&, by the way.

Solution 3

Another technique you can use instead of piping to a bash subprocess is the eval shell built-in for cases where you need the generated shell code to rely on something in your current shell's environment, or you want the output of your program to include actions like setting environment variables in the current shell process.

For example, say your output was more like this:

$ python example.py
PATH="$PATH:/opt/wackysoft/bin"
export PATH
echo $PATH
which wackysoft-command

You might want to keep the changed PATH environment variable in your current session, so you'd use eval. For example:

$ eval "`python example.py`"
/bin:/sbin:/usr/bin:/usr/sbin:/opt/wackysoft/bin
/opt/wackysoft/bin/wackysoft-command
$ echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin:/opt/wackysoft/bin
$ which wackysoft-command
/opt/wackysoft/bin/wackysoft-command

This is similar to how programs like ssh-agent are usually called in .xsession or .profile configuration files.

Share:
7,821

Related videos on Youtube

SabreWolfy
Author by

SabreWolfy

Updated on September 18, 2022

Comments

  • SabreWolfy
    SabreWolfy almost 2 years

    I haven't found a solution to this after some searching. I think the search terms are just too general. I'd like to know how to execute a number of lines (at the bash prompt) which are generated by some other source. For example, I have a Python script which dynamically generates a number of bash commands and prints them to stdout. I'd like those lines to be executed as a bash script without having to save them to disk. For example:

    $ python example.py
    touch 1 2 3 4 5
    rm 1 2 3 4 5
    echo "Done"
    

    I'd like to do something like:

    $ python example.py | executeLines
    

    Does such a command/feature exist in bash? Sometimes one of the commands may exit with a non-zero exit status, so appending && to each command and then running:

    $ `python example.py`
    

    will not always work and seems to be a clumsy solution.

  • SabreWolfy
    SabreWolfy over 12 years
    Thanks. I had no idea it was that simple, so I didn't bother to even try it first :)
  • SabreWolfy
    SabreWolfy over 12 years
    Thanks. I didn't know about using ;. Very useful to know.
  • SabreWolfy
    SabreWolfy over 12 years
    I was posting the following edit to my question, but the answers came in so quickly I didn't get a chance. [Edit: I know that I can execute commands from within Python, but repeatedly calling popen or whatever seems less efficient than just executing a "script".] I wanted a quick and simple solution that allows me to run the Python script first to check that it's outputting the correct commands before piping it to bash, so the accepted solution above does exactly what I want.
  • Vijay Anand Mareddy
    Vijay Anand Mareddy over 12 years
    xargs runs a command with arguments split after some limits. I don't think the poster wants to use the same command and have args split for hime.
  • Jeramey
    Jeramey over 12 years
    Your telnet example is amusing because that's basically how the Ruby Version Manager is recommended to be installed (only replacing a telnet command with a curl one). Bad ideas never die!
  • MadHatter
    MadHatter over 12 years
    My word! I should never have thought to look for it, so thank you for letting me know!