Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have some exports and other things that require another program to run (to get paths or whatever) and they take a non-trivial amount of time to run, meaning my bash startup time is on the order of 5 seconds.

Before I go off and add some basic caching in my .bashrc, is there a way I can run something asynchronously that will allow me to export variables in my running shell?

(So, this really isn't limited to .bashrc, but bash in general.)

share|improve this question

4 Answers 4

A lot depends on when those programs have to run and when you need their results. If it doesn't matter when they run (that is, their results don't vary with time), then it might be better to have them run from your ~/.profile or ~/.bash_profile (i.e., when you log in) rather than from your ~/.bashrc.

If you need their results, but can't wait the 5 seconds it takes for them to run, what are you going to do for the first 5 seconds that your shell is up? You can't run any commands that depend on the outputs of those programs, because the results won't be available yet.

I think if you describe in more detail exactly what the requirements are, we might be able to give you better answers.

All that said, you could launch your programs in the background as Dennis Williamson suggested, and have them write their results to some files in your home directory. Then you could set the bash variable PROMPT_COMMAND to source those files, which bash would then do before every display of PS1.

For example, say your background program writes export ans=42 to the file ~/answer when it's done. In your ~/.bashrc, put

PROMPT_COMMAND=". ~/answer"

Then every time the shell displays PS1, it will first source ~/answer and your environment will eventually (e.g., 5 seconds after starting) contain the variable ans with the value 42.

Of course, the first 5 seconds after you start the shell, ~/answer will contain the values from the last time you started a shell, so you'd have to decide whether that's important (and how to reset that file if necessary).

share|improve this answer

I'm not aware of any way that can set the variables in the background. However, you can run scripts in background such that they run in parallel, rather than sequentially, while catching their output. This can speed up execution. You can use file descriptors 3-9 with this method for a total of 7 parallel processes.

To be clear, all of the commands executed must finish before spawning the interactive shell in order to use their output in setting variables.

This solution simply allows parts of the script to run in parallel to the rest of the script (in this case, the .bashrc)

function copget { read -u $1; echo "$REPLY"; }

coproc DATE { date; }
exec 3<&${DATE[0]}

coproc UNAME { uname; }
exec 4<&${UNAME[0]}

var1=$(copget 3)
exec 3>&-

var2=$(copget 4)
exec 4>&-
share|improve this answer
    
ewindisch, could you add some comments to the right of the exec statements? I can never seem to remember how to properly (and safely!) use the <& and >& forms of redirection. –  Zearin Jan 20 at 16:13

You can use an ampersand to run a process in the background.

some_program &

However, the program won't be able to directly affect the environment of the shell that started it.

You should not have any long-running processes in startup files.

share|improve this answer

You might want to think about balancing the workload between your profile, which is executed once, and your bashrc file, which is executed whenever you start (an interactive) bash. I keep my bashrc minimal - so I get fast start up. My profile isn't too bad - it is complex, but it certainly doesn't take 5 seconds.

share|improve this answer

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.