linux - Copy shell configuration from one machine to another?

07
2014-07
  • Andrius

    I've got login to another server where shell configurations are not like I would want. For example I don't see my username and CWD on prompt, and when I press arrow key, instead of giving last entered command, it gives me ^[[A. So I wonder if can just move my profile configuration from my machine to that server?

    I copied .bashrc and .profile files and tried to execute them, but it didn't do anything. What should I do? Do I need some other files? Or I can only create all configurations from scratch?

  • Answers
  • drk.com.ar

    Actually such configuration could be in different scripts. But you should copy .profile .bash_profile and .bashrc and then logout and login.

  • l0b0

    Keyboard configuration like you mention is usually in ~/.inputrc, which you should be able to copy to most *nix machines.


  • Related Question

    Bash shell: how to reconcile portable configuration files and GUI terminal start-up types (login or interactive)?
  • jmlane

    In an attempt to "properly" implement a standard configuration of my preferred shell, bash, for use across multiple platforms, I've come across some confusion when dealing with terminals that are inconsistent with their choice of shell start-up types (login or interactive).

    Bash Start-Up Files

    From the bash manual, I've determined the difference between the start-up files and order/cases in which they are sourced (/etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile for login shells, and ~/.bashrc for interactive non-login shells). The documentation suggested that you store your bash-specfic login configuration in ~/.bash_profile and your bash-specific interactive ones in your ~/.bashrc. The manual itself even suggested adding if [ -f ~/.bashrc ]; then source ~/.bashrc; fi to the ~/.bash_profile file so login shells inherit your interactive shell settings.

    From what I've read in the manual and in various online forums/docs, it also seemed prudent to abstract your non-bash specific login configuration to ~/.profile since other shells can source this file. This may be an edge-case for people who may use Bourne shell in addition to bash (which is not really likely in my case), but it seems like a good habit to form.

    So far this all seems pretty straight forward and logical, especially in an environment where the distinction between the various shell start-up types are apparent: on systems or terminals where the command-line is the primary interface, login shells are your primary session shells, interactive shells are subsequent shells launched in that session, and your non-interactive shells are script-running shells.

    The real confusion is what constitutes a login shell when your shell is started from a terminal within a GUI environment where you are already authenticated to the system? It seems to me that the default behavior in Mac OSX Terminal.app is for the shell running in each window to start a login shell, whereas in xterm, each new window is an interactive shell.


    It is possible that I am seeing a problem where one does not exist, however consider the following: the terminal situation suggests that I put the vast majority of my configuration in ~/.bashrc to avoid losing functionality should I be working on a terminal that starts bash as an interactive shell. Being unfamiliar with the intricacies of when bash might be spawned as interactive shells, I have to rely on this statement that abusing ~/.bashrc like this will eventually cause problems where login shell configuration being misplaced is detrimental to normal shell functioning. It isn't hard to imagine that problems might arise when you ignore the manual's advice and use configuration files inappropriately.

    Since you can't really rely on using ~/.bashrc as your catch-all, it seems like you might need to treat your ~/.bash_profile and ~/.bashrc files differently depending on the terminal you are using. This seems like it would result in a lot of headaches and is counter to the purpose of having these distinct start-up files in the first place!

    So finally my questions are as follows:

    • How do current Bash shell users address the issue of GUI terminal inconsistencies between starting login and interactive shells?
    • How do you create a single-set of bash start-up files for cross-platform (and cross-terminal) use, without running into problems?

    Thank you for your assistance and advice.


  • Related Answers
  • Gilles

    The most common problem caused by misuse of shell startup files is that if you define environment variables in .bashrc as opposed to .profile, they are not defined in applications that are not launched from a shell in a terminal but rather from a GUI menu.

    Defining environment variables from .bashrc is generally not a good idea, but that's primarily because it's generally useless as the variables should already have been set at login time. It can cause a problem in practice if you (or an application) have deliberately changed the value of a variable (e.g. PATH) in a program and you launch a shell from that program and expect the setting to have remained the same.

    You can avoid the problem of environment variables being reset by defining a “sentinel” value, and not defining anything if the sentinel value is set:

    if [ -z "$JMLANE_PROFILE_READ" ]; then
      export ...
      export JMLANE_PROFILE_READ=1
    fi
    

    Another problem caused by terminals starting login shells is that there are things that should only be done once when you log in, for example starting a password agent (e.g. ssh-agent), or initiating a session (e.g. running startx in certain circumstances). The sentinel variable avoids these issues.

    A shell inside a terminal is always interactive. As long as you source .bashrc from .bash_profile when the shell is interactive, you don't need to worry about the terminal starting a login shell.

    An additional wart of bash's startup file handling is that .bashrc is read by non-interactive shells invoked by rshd or sshd. For example, when you do rsync somefile host.example.com:, if your login shell on host.example.com is bash, you can use .bashrc there to set the path to include rsync. You can tell you're in this situation because .bashrc is read from a non-interactive shell.

    ## .bashrc
    if [[ $- != *i* ]]; then
      # either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
    fi