Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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.

share|improve this question

5 Answers 5

up vote 8 down vote accepted

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.

share|improve this answer
    
Thanks. I had no idea it was that simple, so I didn't bother to even try it first :) –  SabreWolfy Oct 6 '11 at 15:52
    
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! –  Jeramey Oct 6 '11 at 16:33
    
My word! I should never have thought to look for it, so thank you for letting me know! –  MadHatter Oct 6 '11 at 16:36

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.

share|improve this answer
    
Thanks. I didn't know about using ;. Very useful to know. –  SabreWolfy Oct 6 '11 at 15:53

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|improve this answer

Can't you just execute them as sub-processes from inside your Python script, with the help of the os.system call?

share|improve this answer
    
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. –  SabreWolfy Oct 6 '11 at 15:55

What you are looking for is exactly what xargs does.

share|improve this answer
    
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. –  mihi Oct 6 '11 at 16:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.