Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

So let's say I'm developing code in directory /asdf/qwer/dfgh/wert/asdf/qwer and I've added about three more directories like that to my path and I have a bunch of arcane environment variables set. Then I realize that I really need another terminal open and set up in just this same way (although this need is not reoccurring so that I would just alter my .bashrc). Is there any command to open a new terminal window that is an exact clone of this one?

share|improve this question

4 Answers 4

up vote 6 down vote accepted

Cloning the path is easy if you can run your terminal program from the command line. Assuming you're using xterm, just run xterm & from the prompt of the terminal you want to clone. The new xterm will start in the same directory, unless you have it configured to start as a login shell. Any exported environment variables will also carry over, but un-exported variables will not.

A quick and dirty way to clone the whole environment (including un-exported variables) is as follows:

# from the old shell:
set >~/environment.tmp

# from the new shell:
. ~/environment.tmp
rm ~/environment.tmp

If you've set any custom shell options, you'll have to reapply those as well.

You could wrap this whole process into an easily-runnable script. Have the script save the environment to a known file, then run xterm. Have your .bashrc check for that file, and source it and delete it if found.


Alternately, if you don't want to start one terminal from another, or just want more control, you could use a pair of functions that you define in .bashrc:

putstate () {
    declare +x >~/environment.tmp
    declare -x >>~/environment.tmp
    echo cd "$PWD" >>~/environment.tmp
}

getstate () {
    . ~/environment.tmp
}

EDIT: Changed putstate so that it copies the "exported" state of the shell variables, so as to match the other method. There are other things that could be copied over as well, such as shell options (see help set) -- so there is room for improvement in this script.

share|improve this answer
    
Wow... cool explanation that lead to some insights that I have had before. –  John Berryman Jan 19 '11 at 6:32
    
I modded you script to take an argument and place the put and get the environment to a file named by the argument... now I can have several environments! :D –  John Berryman Jan 23 '11 at 20:19
    
Question: what does "." do in getstate? –  John Berryman Jan 23 '11 at 20:26
    
The "." says, "Run the contents of this file using the current shell, as if they were typed at the command line". Without the ".", a new copy of bash would run the commands in the file and then exit, and the current shell's environment wouldn't change. –  Jander Jan 23 '11 at 21:15

If you start a screen (GNU Screen) in your defined environment, that environment will be used by the sub-process (i.e. screen) and you can use it to spawn new terminals. But if you want to fork it another time (a screen in a screen) it begins to be tricky.

share|improve this answer

In a similar situation, I also found it useful to start the new shell in the same directory as the current one. I used a recipe like this to start the shell.

exec ssh -t $HOST "cd $DIR; $SHELL $parms"

The -t option is needed whenever you explicitly run a shell using ssh. It causes a pseudo-tty to be created for the process. This is necessary for history commands and other interactive features to work correctly. Earlier lines in the script set DIR to the current directory and SHELL to the user's preferred shell.

share|improve this answer

while exported variables make it to the other side using the above 'getstate' function, for some reason they end up not being exported there (as can be seen using a simple os.getenv from python). it seems to work better for me when modifying getstate to be an alias:

alias getstate=". ~/environment.tmp"
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.