Ich weiß nicht, ob Sie schon einmal auf ein solches Szenario gestoßen sind, bei dem Sie eine Umgebungsvariable festlegen oder ein Programm ausführen müssen, um Ihre Shell- oder Desktop-Umgebung festzulegen, aber nicht wissen, wo sich der dafür am besten geeignete Ort befindet stellen Sie es ein.
Es gibt einige häufige Situationen, z. B. vom Debian-Paketmanager bis zur Iaas-Verwaltung müssen viele Aufgaben Umgebungsvariablen festlegen, um ordnungsgemäß ausgeführt zu werden.
Manchmal muss ein Programm bei der ersten Anmeldung nur einmal ausgeführt werden, beispielsweise der Befehl xrandr.
Darüber hinaus werden gelegentlich Programme in die Shell eingefügt, beispielsweise rbenv, rvn oder SitePoints eigenes envswith-Programm.
Werfen wir einen Blick auf einige gängige Optionen, die in Debian GNU/Linux Jessie-Installationen angezeigt werden, und versuchen wir, alles zu verstehen.
/etc/profile
Standardmäßig stellt Debian die Datei /etc/profile bereit. Diese Datei wird zum Festlegen der Variablen $PATH verwendet ($PATH wird normalerweise zum Deklarieren des Suchpfads verwendet). Befehle). Sie können dies ab sofort tun. Der folgende Code ist Teil von /etc/profile.
if [ "`id -u`" -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" fi export PATH
Der Einfachheit halber unterscheidet sich der Pfad für den Root-Benutzer (ID 0) von dem für alle anderen Benutzer. Dies liegt daran, dass der Speicherort des Systembinärverzeichnisses (Sbin-Verzeichnis) traditionell für Systemverwaltungsprogramme oder Programme reserviert ist, die als Root ausgeführt werden müssen. Der Spielepfad wird für den Root-Benutzer weggelassen, da es unmöglich ist, den Root-Benutzer zum Ausführen des Spielprogramms zu verwenden, es sei denn, dies ist erforderlich.
Als nächstes übernimmt /etc/profile die Einstellung der Variablen $PS1. Die Variable $PS1 wird verwendet, um die Hauptaufforderungszeichenfolge festzulegen (d. h. die Zeichen, die beim Anmelden des Benutzers angezeigt werden). Abgesehen davon, dass die System-Shell Bash ist, ist die Systemvariable $PS1 standardmäßig auf $ gesetzt (der Standardwert für Root-Benutzer ist #). Wenn die Shell des Systems Bash verwendet, ersetzt die Datei /etc/bash.bashrc die Variable $PS, um die Hauptaufforderungszeichenfolge zu verarbeiten (außer in besonderen Fällen). Wir werden später kurz auf /etc/bash.bashrc eingehen.
Von diesem Punkt aus können wir also ableiten, dass /etc/profile von allen Shells während der Anmeldung gelesen wird (z. B. mit dem Login-Befehl). /etc/profile ruft den Befehl id auf, um die Benutzer-ID zu lesen, anstatt die effizientere integrierte Bash-Variable ${UID} zu verwenden. Bash verwendet quellenspezifische Konfigurationen, anstatt eine ausgefallene Shell-Eingabeaufforderung zu definieren, da Bash Sonderzeichen mit Backslash-Escapezeichen wie u (Benutzername) und h (Hostname) unterstützt, die viele andere Shells nicht definieren. /etc/profile sollte versuchen, POSIX-kompatibel zu sein, um mit allen Shells kompatibel zu sein, die Benutzer möglicherweise selbst installieren.
Debian GNU/linux wird normalerweise mit Dash vorinstalliert, einer Basis-Shell, die nur für die Implementierung von POSIX-Erweiterungen (und einigen Berkeley-Erweiterungen) entwickelt wurde. Wenn wir /etc/profile ändern (vor der Änderung sichern), um einen anderen Wert für die Zeile PS1='$ ' festzulegen, und dann eine Dash-Anmeldung simulieren (über den Befehl dash -l), können wir sehen, dass Dash unsere verwendet individueller Hinweis. Wenn wir jedoch den Befehl dash ohne den Parameter -l aufrufen, liest dash /etc/profile nicht. Zu diesem Zeitpunkt verwendet Dash den Standardwert (was bedeutet, dass der Wert von PS1 zu diesem Zeitpunkt der Wert ist, bevor wir ihn geändert haben).
Das letzte Interessante im Zusammenhang mit /etc/profile ist der folgende Codeausschnitt:
if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi
Mit anderen Worten, alles, was mit /etc/profile.d/*.sh übereinstimmt, ist lesbar Der Inhalt wird als variable Quelle behandelt. Dies ist sehr wichtig, da es zeigt, dass eine direkte Bearbeitung von /etc/profile nie wirklich notwendig ist (stellen Sie also Ihr vorheriges Backup wieder her). Alle oben definierten Variablen können in einer separaten Datei konfiguriert werden und dann die Einstellungen in /etc/profile überschreiben. Dies hat den Vorteil, dass die entsprechenden Änderungen bei einem System-Upgrade automatisch in die Datei /etc/profile eingefügt werden können. Weil das Apt-Paketverwaltungssystem von Debian die Standardkonfigurationsdatei normalerweise nicht ändert.
~/.bash_profile, ~/.bash_login und ~/.profile
Ein potenzielles Problem mit /etc/profile besteht darin, dass es sich in einem systemweiten Pfad befindet. Das bedeutet, dass sich eine Änderung auf alle Benutzer dieses Systems auswirkt. Auf einem PC stellt dies möglicherweise kein allzu großes Problem dar, für die Änderung sind jedoch auch Root-Rechte erforderlich. Aus diesen Gründen kann jedes einzelne Bash-Benutzerkonto eine der Dateien ~/.bash_profile, ~/.bash_login und ~/.profil als Quelle für Bash-Konfigurationsdateien erstellen. Die erste in der aufgeführten Reihenfolge gefundene Datei wird als Konfigurationsdatei verwendet, der Rest wird ignoriert.
Andere Shells wie Dash unterstützen etwas Ähnliches, suchen aber nur nach ~/.profile-Dateien. Dadurch können Benutzer eine separate .bash_profile-Datei für Bash-spezifische Anwendungsfälle konfigurieren, wenn sie irgendwann zu Dash oder einer anderen Shell als Anmelde-Shell wechseln müssen (z. B. über den Befehl chsh -s dash). ~/.profile kann als Konfigurationsdatei für diese Shells beibehalten werden.
需要牢记的一点是,默认的Debian框架目录(/etc/skel,用于存放要复制到新用户账户主目录的文件和目录)包含.profile文件,但不包含.bash_profile和.bash_login文件。此外Debian使用Bash作为默认的shell,因此,许多Debian用户习惯于将他们的Bash 登录shell设置放在.profile文件中。
我曾经看到过一些项目的安装说明,例如RVN,这个项目建议用户创建一个.bash_profile文件,但是这样做是非常危险的,根据上面提到的知识我们知道,这个会改变用户的shell环境。即使用户没有修改.profile文件,它也可能利用默认~/.profile功能,将~/bin添加到$PATH环境变量。一个可能提高安全性的选项是,在创建用户的账户之前,将.bash_profile作为.bash_rc的符号链接文件,放到/etc/skel目录中。
如果我们查看Debian Jessie的默认.profile脚本,我们可以看到下面的代码片段:
# if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi
这和我们在/etc/profile里面看到的相似,如果shell是Bash,且发现了/etc/bash.bashrc文件,/etc/bash.bashrc文件就被当作Bash的配置文件。这一点的意义将在下一节讨论。
/etc/bash.bashrc 和 ~/.bashrc
启动的时候,Bash会同时读取/etc/bash.bashrc和~/.bashrc,但是只有在Bash Shell作为交互式Shell而不是登录Shell启动时(意味着通过xtem启动),会依照这种顺序,这是Bash Shell的标准行为。然而,Debian分别从 /etc/profile和~/.profile登录脚本中获取配置文件。这会显著地改变行为,使得/etc/bash.bashrc和.bashrc(如果它们存在)总是在Bash启动时调用,而不管是不是登录Shell。不要期待这种情况在不同地发行版中是一样的。
.bashrc是一个添加命令别名的好地方,实际上,一些用户拥有太多的别名,以至于他们宁愿将别名都放在一个单独的文件中去。Debian的默认.bashrc会查找.bash_alias,如果这个文件存在的话,会将它作为别名配置来源。所以你可以在这个文件中随意保存所有的Bash别名。如果用户愿意的话,.bashrc文件也是用户重写shell变量,例如$PS1或者$HISTSIZE的绝佳位置。Debian的默认.bashrc有超过100行,但是仍然可以非常清晰地阅读,且有良好地注释。见名知意,.bashrc不是其他非Bash shell的配置文件来源。
~/.xsession 和 ~/.xsessionrc
如果你是一个GNU/Linux桌面用户,通过显示管理器本地登录(而不是通过getty登录程序),则/etc/profile和~/.profile不会像预期的那样工作。一些显示管理器会直接将这些文件视为错误地配置文件,例如Gnome显示管理器。但一些其他的显示管理器,例如LightDm不会这样。幸运的是,你还有一些其他的选项。
当启动X Window系统会话时(不管是用显示管理或从虚拟终端启动startx),将会执行/etc/X11/Xsessionshell脚本。这基本上相当于登录shell调用/etc/profile。这个只对X Window生效,并且不是将其作为源配置文件,而是直接执行。但是它也相当复杂,类似于/etc/profile怎么从/etc/profile.d目录中的脚本读取配置,怎么从/etc/X11/Xsession.d/目录下的/etc/X11/Xsessions脚本中读取配置。在/etc/X11/Xsession.d目录下的所有脚本名称都以数字开头,因此所有的脚本都会按照数字顺序来读取。
Debian Jessie包含一个名叫40×11-common_xsessionrc的文件,这个文件做的工作就是检查~/.xsessionrc是不是可读的,如果是就用它作为配置文件的来源。这就使得~/.xsessions是一个加载环境变量或者运行一个一次性使用程序(例如xrandr或xmodmap)的完美位置(仅适用于X会话)。如果你希望的话,你同样可以将/etc/profile或~/.profile作为来源。那么任何指定的环境变量也都会被你的会话管理器继承(如果还没有继承的话)。请注意,默认情况下.xsessionrc是不存在的,需要你自己创建这个文件。
如果我们继续浏览/etc/X11/Xsession中的文件, 我们会发现50×11-common_determine-startup会决定加载哪个会话管理器。如果~/.xsessions文件存在而且是可执行的,它会被保存并且随后作为99×11-common_start的一部分执行,当~/.xsession用于运行会话管理器,X会话将会被注销。并且当这个脚本终止时,你会返回到显示管理器登录界面。
和~/.xsessionrc相似,~/.xsession默认也是不存在的,在你需要的时候你可以创建一个。你可能会创建一个类似下面给的简单的.xsession脚本
# Start our session manager of choice. # exec x-session-manager
其中x-session-manager默认设置为通过update-alternatives命令配置的任何内容,这样,你可以轻松地更改系统范围默认地会话管理器,只需要将x-session-manager替换为/usr/bin/startfce4(切换到XFCE),其他的用户账户将完全不受影响。
当然,许多显示管理器提供从登录界面直接选择公共会话管理器的能力,所以这个文件通常是不必要的。然而.xsession提供了更多地灵活性,你可以用任何程序调用这个文件,而不仅仅是会话管理器。例如,在这里你可以在while循环中调用chromium或者iceweasel,而不是执行基本的kiosk模式设置。
~/.bash_logout
我们前面介绍了当用户运行交互式Bash登录shell时读取的文件,但是如果你想在注销以后仍然运行程序该怎么办?对于这个用例,~/.bash_logout文件就非常方便了。在Debian中默认的配置仅用于清除屏幕(我认为从安全角度来说很重要),但是可以轻微地想象以下就知道能用于其他目的,例如,在你离开你的机器之前显示一个几秒钟的提醒。
主要的限制因素在于.bash_logout仅在注销交互式shell时读取,并且并不能假定它在注销X会话时会被加载。
其他选项
上面那些已经为你介绍了大部分的通用选项。其他的选项可能会存在,取决于你的安装环境(例如/etc/environment),但是我不认为他们可能在其他的平台上存在,并且极少有需要去接触它们。
示例
那么你应该在哪放置你的系统范围环境变量?如果你希望一个环境变量可以影响所有用户,/etc/profiled./someifle.sh会是一个好的选择。但是,这假设你是使用一个登录管理器以/etc/profile作为配置来源。如果不是这样,你可以(作为一个管理员)添加一个脚本到/etc/X11/Xsession.d/来替代/etc/profile作为配置来源。
如果你希望一个脚本可以找到一个私人目录路径,并且添加它到你的PATH中,你需要考虑这个目录是不是会移动很多东西,如果你向.profile添加代码来实现,用户需要注销然后再登录来更改用户会话期间的PATH。如果你将代码添加到.bashrc中,这意味着代码将在用户每次打开xterm时执行,如果执行大约半秒以上可能就不太理想。所以这是一个权衡取舍的问题。
如果你仅仅是为了你个人登录会话时的一个环境变量,且它只关心X会话,你可以将它添加到~/.xsessionrc中。这样做的优点是,它通常将可用于通过X会话管理器启动的所有程序,因为它在启动X会话管理器之前被设置,并且被继承。例如,某些图形驱动程序可以通过运行
export vblank_mode=0
来禁用vsync。 所以位于.xsessionrc中的变量会影响到所有的程序。
然而如果这一行被添加到.bashrc中,则只有通过xterm登录的程序会被影响。通过一个窗口管理器启动的程序照常运行。你可以把它添加到.profile,并且从.xessionrc作为.profile的来源。但是之后,当你的X服务没有在运行的时候,你就不需要导出环境变量。
希望你现在可以更好地了解了登录和注销脚本在Debian GNU/Linux系统上的工作原理。