问题描述
我是Ubuntu的新手。我正在运行13.10桌面。
我想设置一些系统范围的别名和bash的自定义提示。我找到了这篇文章:
https://help.ubuntu.com/community/EnvironmentVariables
按照本文中的建议,我创建了/etc/profiles.d/profile_local.sh。它由root拥有,具有644的权限,就像其他脚本一样:
root@ubuntu:/etc/profile.d# ll
total 28
drwxr-xr-x 2 root root 4096 Mar 23 08:56 .
drwxr-xr-x 135 root root 12288 Mar 23 09:15 ..
-rw-r--r-- 1 root root 660 Oct 23 2012 bash_completion.sh
-rw-r--r-- 1 root root 3317 Mar 23 07:36 profile_local.sh
-rw-r--r-- 1 root root 1947 Nov 23 00:57 vte.sh
我进一步确认/etc /profile调用/etc/profile.d。它包含此代码块:
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
登录后,我创建的自定义脚本profile_local.sh似乎没有获取。但是,如果登录后我’source /etc.profile.d/profile_local.sh’,我会得到预期的行为,我的自定义别名和自定义提示。
我究竟做错了什么?
脚本’profile_local.sh’的内容:
# 3/23/14 - Copied from Gentoo /etc/bash/bashrc
# Placed in /etc/profile.d as described at:
# https://help.ubuntu.com/community/EnvironmentVariables
# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output. So make sure this doesn't display
# anything or bad things will happen !
# Test for an interactive shell. There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
# Shell is non-interactive. Be done now!
return
fi
# Bash won't get SIGWINCH if another process is in the foreground.
# Enable checkwinsize so that bash will check the terminal size when
# it regains control. #65623
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
shopt -s checkwinsize
# Enable history appending instead of overwriting. #139609
shopt -s histappend
# Change the window title of X terminals
case ${TERM} in
xterm*|rxvt*|Eterm|aterm|kterm|gnome*|interix)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
;;
screen)
PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
;;
esac
use_color=false
# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS. Try to use the external file
# first to take advantage of user additions. Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?} # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs} ]] \
&& type -P dircolors >/dev/null \
&& match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true
if ${use_color} ; then
# Enable colors for ls, etc. Prefer ~/.dir_colors #64489
if type -P dircolors >/dev/null ; then
if [[ -f ~/.dir_colors ]] ; then
eval $(dircolors -b ~/.dir_colors)
elif [[ -f /etc/DIR_COLORS ]] ; then
eval $(dircolors -b /etc/DIR_COLORS)
fi
fi
if [[ ${EUID} == 0 ]] ; then
PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
else
PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
fi
alias ls='ls --color=auto'
alias grep='grep --colour=auto'
else
if [[ ${EUID} == 0 ]] ; then
# show root@ when we don't have colors
PS1='\u@\h \W \$ '
else
PS1='\u@\h \w \$ '
fi
fi
# Try to keep environment pollution down, EPA loves us.
unset use_color safe_term match_lhs
TZ="PST8PDT"
alias ll='ls -la'
alias dig='dig +search'
alias dir='ls -ba'
alias edit="ee"
alias ss="ps -aux"
alias dot='ls .[a-zA-Z0-9_]*'
alias news="xterm -g 80x45 -e trn -e -S1 -N &"
alias more="less"
alias c="clear"
alias m="more"
alias j="jobs"
# common misspellings
alias mroe=more
alias pdw=pwd
最佳解决思路
要了解这里发生了什么,您需要了解有关如何运行shell(在这种情况下为bash)的一些背景信息。
-
当您打开终端仿真器(例如
gnome-terminal
)时,您正在执行所谓的交互式non-login shell。 -
当您从命令行,通过
ssh
登录计算机或运行命令(如su - username
)时,您正在运行交互式登录shell。 -
当您以图形方式登录时,您运行的是完全不同的东西,详细信息将取决于您的系统和图形环境,但通常它是处理您的登录的图形 shell 。虽然许多图形shell(包括Ubuntu默认)将读取
/etc/profile
,但并非所有图形shell都可以。 -
最后,当您运行shell脚本时,它将在non-interactive,non-login shell中运行。
现在,bash在启动时将读取的文件取决于它运行的shell的类型。以下是man bash
(强调我的)INVOCATION部分的摘录:
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.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. 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 /etc/bash.bashrc and ~/.bashrc.
这一切意味着您正在编辑错误的文件。您可以使用Ctrl
+ Alt
+ F2
(根据您的设置返回到Alt
+ F7
或F8
的GUI)并登录到虚拟控制台进行测试。您将看到您的提示和别名可用。
因此,为了将您想要的设置应用于non-login shell(每次打开终端时获得的类型),您应该对~/.bashrc
进行更改。或者,您也可以将别名放在文件~/.bash_aliases
中(但请注意,这是一个Ubuntu功能,您不应期望它可以在其他发行版上工作)。
有关应使用哪个文件的更多详细信息,请参阅here。
笔记:
-
Debian(以及扩展名为Ubuntu)也有默认的
~/.profile
源~/.bashrc
。这意味着您对~/.bashrc
所做的任何更改也将由登录shell继承,但是i)在所有Linux /Unix机器中都不是这种情况,并且ii)反之亦然,这就是为什么您通常应该始终使用~/.bashrc
&而不是~/.profile
或/etc/profile
。 -
此外,关于使用情况的一般说明,对
/etc
中的配置文件所做的更改将影响所有用户。这通常不是您想要做的,应该避免。您应该始终使用主目录中的等效文件(~/
)。 -
按顺序读取各种配置文件。具体来说,对于登录shell,订单是:
/etc/profile -> /etc/profile.d/* (in alphabetical order) -> ~/.profile
这意味着
~/.profile
中的任何设置都将覆盖先前文件中设置的任何内容。