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.

The shell that I normally use is zsh. I have several aliases to enable color in some programs such as ls and grep. I've also set my custom path so that I can execute programs in non-standard place (such as in ~/bin/).

I won't change root's shell to zsh, but I would like to share these setting so that root can have it as well. I find out that zsh is not sourcing /etc/profile. I can source it in /etc/zsh/zprofile, but I would like some other more "proper" way.

share|improve this question

4 Answers 4

up vote 9 down vote accepted

I'd create a file /etc/commonprofile and source it in both /etc/profile and /etc/zsh/zprofile. This gives you the opportunity to share common settings and still use bash respectively zsh specific settings and syntax in /etc/profile respectively zprofile.

share|improve this answer
    
among other good answers I think this one suits me the best, relatively simple and "clean" –  phunehehe Oct 24 '10 at 12:05

Zsh has an sh compatibility mode which will let it execute POSIX sh code and some bash extensions. As long as you don't use bash features that zsh doesn't have (with the same syntax), you can have the same file sourced by both shells. Use the emulate built-in to put zsh in compatibility mode; with the -L option, the emulation is local to the enclosing function (not the enclosing sourced script).

source_sh () {
  emulate -LR sh
  . "$@"
}

For things like environment variables, you can use source_sh /etc/profile in /etc/zprofile and source_sh ~/.profile in ~/.zprofile, since the profile files aren't likely to use bash-specific features.

For things like aliases and function definitions, since the shell rc files are likely to contain a lot of things that can't be shared (prompt, key bindings, completion settings, …), use a file like ~/.sh_aliases that is sourced in ~/.bashrc and source_sh'd in ~/.zshrc.

share|improve this answer
2  
There should be a way to say "automatically upvote all answers by Gilles". This would save me quite some time. No really, your answers rock. Always accurate, well written and comprehensive. –  fschmitt Oct 23 '10 at 21:14
    
@fschmitt: I agree. And you can see it's not even edited! This hint provided here is really good. –  Somebody still uses you MS-DOS Dec 16 '10 at 20:11

What about a simple symlink?

ln -s /etc/profile /etc/zsh/zprofile

You can also append something like this if you need some conditional initialization:

#Determine our shell without using $SHELL, which may lie
shell="sh"
if test -f /proc/mounts; then
   case $(/bin/ls -l /proc/$$/exe) in
        *bash) shell=bash ;;
        *dash) shell=dash ;;
        *ash)  shell=ash ;;
        *ksh)  shell=ksh ;;
        *zsh)  shell=zsh ;;
    esac
fi
share|improve this answer
    
Hmm but I don't think this will be any cleaner than sourcing it. Is there a file that both zsh and bash will read? –  phunehehe Oct 23 '10 at 15:38
    
what makes you think that sourcing or creating a symlink is not a "clean" solution? –  echox Oct 23 '10 at 19:40
    
I just meant to say if needed, I'd like to source the file rather than to manage the symlink. I don't want to create a lot of dependency between files. –  phunehehe Oct 24 '10 at 6:24
1  
A more portable alternative to /bin/ls -l /proc/$$/exe is ps -o comm= -p $$. This isn't fully reliable because some shells behave differently depending on how they were invoked; in practice simply testing $0 in .profile is likely to be a better indication. But most shells that offer useful features (bash, ksh, zsh) can be simply recognized (and their version identified, which is a big plus) by testing some variables: $BASH, $BASH_VERSION, $BASH_VERSINFO; $KSH_VERSION, ${.sh.version}; $ZSH_VERSION. –  Gilles Nov 20 '10 at 0:10
    
echox, your case statement does not correctly detect zsh4 #Determine our shell without using $SHELL, which may lie shell="sh" if test -f /proc/mounts; then case $(/bin/ls -l /proc/$$/exe) in bash) shell=bash ;; *dash) shell=dash ;; *ash) shell=ash ;; *ksh) shell=ksh ;; *zsh) shell=zsh ;; #matches zsh4 esac fi –  Bryan Hunt Jan 26 '11 at 19:28

As regards variables, I have the impression that you are missing modules & modulefiles [1]. Once you start doing so, it will be easy to create common profiles for various shells (incl. bash & zsh), python, perl and even more environments, all from the convenience of a single module file.

It is also possible to define aliases in the same way; however, you will quickly find that aliases do not get inherited very well between successive shells and may need workarounds.

[1] http://en.wikipedia.org/wiki/Environment_Modules_(software)

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.