個人.bashrc:
~/.bashrc:
# .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi
全局bashrc:
/etc/bashrc:
# /etc/bashrc # System wide functions and aliases # Environment stuff goes in /etc/profile # It's NOT a good idea to change this file unless you know what you # are doing. It's much better to create a custom.sh shell script in # /etc/profile.d/ to make custom changes to your environment, as this # will prevent the need for merging in future updates. # are we an interactive shell? if [ "$PS1" ]; then if [ -z "$PROMPT_COMMAND" ]; then case $TERM in xterm*|vte*) if [ -e /etc/sysconfig/bash-prompt-xterm ]; then PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm elif [ "${VTE_VERSION:-0}" -ge 3405 ]; then PROMPT_COMMAND="__vte_prompt_command" else PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' fi ;; screen*) if [ -e /etc/sysconfig/bash-prompt-screen ]; then PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen else PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' fi ;; *) [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default ;; esac fi # Turn on parallel history shopt -s histappend history -a # Turn on checkwinsize shopt -s checkwinsize [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ " # You might want to have e.g. tty in prompt (e.g. more virtual machines) # and console windows # If you want to do so, just add e.g. # if [ "$PS1" ]; then # PS1="[\u@\h:\l \W]\\$ " # fi # to your custom modification shell script in /etc/profile.d/ directory fi if ! shopt -q login_shell ; then # We're not a login shell # Need to redefine pathmunge, it get's undefined at the end of /etc/profile pathmunge () { case ":${PATH}:" in *:"$1":*) ;; *) if [ "$2" = "after" ] ; then PATH=$PATH:$1 else PATH=$1:$PATH fi esac } # By default, we want umask to get set. This sets it for non-login shell. # Current threshold for system reserved uid/gids is 200 # You could check uidgid reservation validity in # /usr/share/doc/setup-*/uidgid file if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi SHELL=/bin/bash # Only display echos from profile.d scripts if we are no login shell # and interactive - otherwise just process them to set envvars for i in /etc/profile.d/*.sh; do if [ -r "$i" ]; then if [ "$PS1" ]; then . "$i" else . "$i" >/dev/null fi fi done unset i unset -f pathmunge fi # vim:ts=4:sw=4
用戶的bashprofile:
~/.bash_profile
# .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin export PATH
[root@ckl1 bashtest]# echo $HOME /root
全局profile:
"/etc/profile"
# /etc/profile # System wide environment and startup programs, for login setup # Functions and aliases go in /etc/bashrc # It's NOT a good idea to change this file unless you know what you # are doing. It's much better to create a custom.sh shell script in # /etc/profile.d/ to make custom changes to your environment, as this # will prevent the need for merging in future updates. pathmunge () { case ":${PATH}:" in *:"$1":*) ;; *) if [ "$2" = "after" ] ; then PATH=$PATH:$1 else PATH=$1:$PATH fi esac } if [ -x /usr/bin/id ]; then if [ -z "$EUID" ]; then # ksh workaround EUID=`/usr/bin/id -u` UID=`/usr/bin/id -ru` fi USER="`/usr/bin/id -un`" LOGNAME=$USER MAIL="/var/spool/mail/$USER" fi # Path manipulation if [ "$EUID" = "0" ]; then pathmunge /usr/sbin pathmunge /usr/local/sbin else pathmunge /usr/local/sbin after pathmunge /usr/sbin after fi HOSTNAME=`/usr/bin/hostname 2>/dev/null` HISTSIZE=1000 if [ "$HISTCONTROL" = "ignorespace" ] ; then export HISTCONTROL=ignoreboth else export HISTCONTROL=ignoredups fi export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL # By default, we want umask to get set. This sets it for login shell # Current threshold for system reserved uid/gids is 200 # You could check uidgid reservation validity in # /usr/share/doc/setup-*/uidgid file if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi for i in /etc/profile.d/*.sh ; do if [ -r "$i" ]; then if [ "${-#*i}" != "$-" ]; then . "$i" else . "$i" >/dev/null fi fi done unset i unset -f pathmunge #java environment export JAVA_HOME=/usr/local/jdk1.8.0_161 export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar export PATH=$PATH:${JAVA_HOME}/bin
關於別名:
別名,典型的如ll,是ls -l 的別名,那么這個別名定義在哪呢,其實是在/etc/profile.d/colorls.sh 中,也就是我在上面幾個文件中,標紅的部分。
colorls.sh:

# color-ls initialization # Skip all for noninteractive shells. [ ! -t 0 ] && return #when USER_LS_COLORS defined do not override user LS_COLORS, but use them. if [ -z "$USER_LS_COLORS" ]; then alias ll='ls -l' 2>/dev/null alias l.='ls -d .*' 2>/dev/null INCLUDE= COLORS= for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \ "$HOME/.dir_colors" "$HOME/.dircolors"; do [ -e "$colors" ] && COLORS="$colors" && \ INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`" && \ break done [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \ COLORS="/etc/DIR_COLORS.$TERM" [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ [ "x`/usr/bin/tty -s && /usr/bin/tput colors 2>/dev/null`" = "x256" ] && \ COLORS="/etc/DIR_COLORS.256color" [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \ COLORS="/etc/DIR_COLORS" # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return if [ -e "$INCLUDE" ]; then TMP="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`" [ -z "$TMP" ] && return /usr/bin/cat "$INCLUDE" >> $TMP /usr/bin/grep -v '^INCLUDE' "$COLORS" >> $TMP eval "`/usr/bin/dircolors --sh $TMP 2>/dev/null`" /usr/bin/rm -f $TMP else eval "`/usr/bin/dircolors --sh $COLORS 2>/dev/null`" fi [ -z "$LS_COLORS" ] && return /usr/bin/grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return fi unset TMP COLORS INCLUDE alias ll='ls -l --color=auto' 2>/dev/null alias l.='ls -d .* --color=auto' 2>/dev/null alias ls='ls --color=auto' 2>/dev/null (END)
所以,什么情況下可以執行別名呢:
1:執行了/etc/profile
2:執行了~/.bashrc,~/.bashrc中引用了 /etc/bashrc(在該文件中,執行了ll別名所在的colorls.sh文件)
3:執行了~/.bash_profile,因為該文件中判斷是否存在~/.bashrc,存在的話,會去執行~/.bashrc;根據上一步的結論,自然也就可以執行別名。
ok。那么,進一步,什么情況會執行上述的兩種情況:
第一種情況(/etc/profile):
查閱了man bash后,發現:
1.交互的登錄shell,或者--login選項的非交互shell。
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes
commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile,
in that order, and reads and executes commands from the first one that exists and is readable.
The --noprofile option may be used when the shell is started to inhibit this behavior.
不過在我的centos7中,~/.profile不存在。
第二種情況(~/.bashrc):
1.交互的,但不是登錄的shell。
When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.
This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.
第三種情況(~/.bash_profile):
同情況1。
Shell的幾種類型:
ok。那么看了上面兩種還是很蒙,那么我們再科普下什么是交互shell、非交互shell、登錄shell和非登錄shell。
我是參考了這里:https://blog.csdn.net/wisgood/article/details/52043522
我的理解:
登錄shell:
ssh登錄的,就是登錄shell,登錄shell要退出的話,是執行logout。比如我們用的putty、securtCRT。
非登錄shell:
登錄成功了之后,或者並沒有進行遠程登錄,直接就在本機的(VMVARE的虛擬機中的shell都不能算,可采用下面的方法測試)ubuntu打開終端,這種,我理解的就是非登錄shell。
我做了個小實驗,我是secureCRT遠程到該服務器的,在/home/upload/bashtest/a.sh中,我寫了句logout:
[root@ckl1 bashtest]# less a.sh
#/bin/bash
logout
執行該腳本:
[root@ckl1 bashtest]# ./a.sh
結果:
./a.sh: line 3: logout: not login shell: use `exit'
區分登錄與非登錄shell的好辦法:
(https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell)
1.通過echo $0,如果結果是-bash,那就是login shell。否則不是。
2.如果可以執行logout命令,那么就是login shell;否則不是。
交互shell:
就是我們不管是用SecurtCRT這樣的工具進入遠程服務器也好,或者本機打開終端也好,都可以執行各種命令
在執行這些命令時,shell是可以和我們互動的,比如要求我們輸入東西,比如按Tab可以提示,等等。
非交互Shell:
shell腳本執行,一般來說就是非交互的,我們寫好了腳本,只要交給shell執行就好,期間不需要和我們交互。命令輸入錯了,會直接提示並退出。
以上兩種,其實是不同維度,可以兩兩組合
交互 | 非交互 | |
登錄 | 遠程登錄ssh,調用的文件包括:/etc/profile,~/.bash_profile,~/.bash_login,~/.profile | 較少見,可能讀/etc/profile , ~/.profile。也可能不讀。依然請參考第一個答案:https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell |
非登錄 | 本機打開終端,調用文件包括:~/.bashrc | 執行shell腳本,調用文件包括:BASH_ENV 指定的文件 |
非交互shell中,怎么才能使用別名:
參考:
https://stackoverflow.com/questions/1615877/why-aliases-in-a-non-interactive-bash-shell-do-not-work
方式1:
shopt -s expand_aliases
不過我的centos 7,未生效。
方式2:
source their .bashrc
at the end of their profile。
也就是在~/.bash_profile中新增一行:source ~/.bashrc
但是我這邊依然沒生效。
方式3:
直接腳本中增加:source ~/.bashrc
#/bin/bash ls -l echo "ll " source ~/.bashrc ll
ok。可以正常工作。
ssh執行遠程命令時,怎么才能使用別名:
1.
首先修改遠程主機的~/.bashrc,新增一行:
shopt -s expand_aliases
ssh -t @host ll
2.
ssh @host 'bash -ci ll'
參考:
https://stackoverflow.com/questions/1615877/why-aliases-in-a-non-interactive-bash-shell-do-not-work