[ -n "$PS1" ] in [ -n "$PS1" ] && source ~/.bash_profile;的目的是什么?这一行包含在dotfiles的.bashrc 存储库中。
发布于 2018-08-15 04:57:59
这是检查shell是否是交互式的。在这种情况下,只有在shell是交互式的情况下才能找到~/.bash_profile文件。
参见bash手册中的“这是壳牌互动吗?”,它引用了这个特定的成语。(它还建议通过测试$-特殊变量是否包含i字符来检查shell是否是交互式的,这是解决此问题的更好方法。)
发布于 2018-08-15 06:31:07
这是一种广泛的测试shell是否是交互式的方法。注意,它只在bash中工作,它不适用于其他shell。因此,对于.bashrc来说,这是可以的(如果愚蠢的话),但是它不能在.profile中工作(通过sh读取,bash只是sh的可能实现之一,而不是最常见的实现之一)。
交互式shell将壳变量PS1设置为默认提示符字符串。因此,如果shell是交互式的,则设置PS1 (除非用户的.bashrc删除了它,这不可能发生在.bashrc顶部,而且您可以认为这样做是愚蠢的)。
相反,在bash中是正确的:在bash未设置PS1的非交互实例启动时。请注意,这个行为是特定于bash的,并且可以说是一个错误(为什么bash -c '… do stuff with $var…'在var是PS1时不能工作?)但是bash的所有版本,包括4.4 (我写的最新版本)都是这样做的。
许多系统将PS1导出到环境中。这是个坏主意,因为许多不同的shell使用PS1,但语法不同(例如,巴什迅速逃脱与兹什迅速逃脱完全不同)。但是它是足够广泛的,在实践中,看到PS1是设置的,并不是一个可靠的指示,表明shell是交互式的。外壳可能继承了环境中的PS1。
.bashrc是bash在启动时读取的交互式文件。一个鲜为人知的事实是bash也读取.bashrc是一个登录shell,bash的启发式分析得出这是一个远程会话(bash检查它的父会话是rshd还是sshd)。在第二种情况下,不太可能在环境中设置PS1,因为还没有运行点文件。
但是,代码使用这些信息的方式是适得其反的。
.bash_profile。但是.bash_profile是一个登录时脚本。它可能运行某些程序,这些程序的目的是每个会话只运行一次。它可能覆盖用户在运行该shell之前故意设置为不同值的一些环境变量。在非登录shell中运行.bash_profile是破坏性的。.bash_profile。但是,加载.bash_profile可能很有用,因为非交互式登录shell不会自动加载/etc/profile和~/.profile。我认为人们这么做的原因是那些通过GUI登录的用户(一个非常常见的例子),他们把环境变量设置放在.bash_profile而不是.profile中。大多数GUI登录机制都调用.profile,而不是.bash_profile (读取.bash_profile需要作为会话启动的一部分运行bash,而不是sh)。通过这种配置,当用户打开一个终端时,他们将得到他们的环境变量。但是,用户不会在GUI应用程序中获得他们的环境变量,这是一个非常常见的混乱来源。这里的解决方案是使用.profile而不是.bash_profile来设置环境变量。在.bashrc和.bash_profile之间添加一个桥梁会产生更多的问题,而不是解决问题。
有一种简单、可移植的方法来测试当前的shell是否是交互式的:测试是否启用了选项-i。
case $- in
*i*) echo "This shell is interactive";;
*) echo "This shell is not interactive";;
esac如果shell是非交互式的- i.e,那么这在.bashrc中对读取 .profile <#>only是有用的。如果bash是(非交互式的)登录shell,请读取.profile,如果是交互式shell,则不要读取它。
if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi发布于 2018-08-15 09:41:10
这个奇怪的概念似乎是由于bash开始时不是POSIX克隆,而是Bourne Shell克隆的结果。
因此,POSIX交互行为($ENV被调用为交互式shell)后来被添加到bash中,并不广为人知。
有一个shell允许类似的行为。这是csh和csh授权,$prompt具有特定的值:
$prompt not set non-interactive shell, test $?prompt.
$prompt set but == "" .cshrc called by the which(1) command.
$prompt set and != "" normal interactive shell.但这既不适用于Bourne Shell,也不适用于POSIX Shell。
对于POSIX shell,唯一授予的方法是将交互式shell的代码放入文件中:
$ENV它有一个特定于shell的名称。它是。
$HOME/.kshrc for the korn shell
$HOME/.bashrc for bash
$HOME/.mkshrc for mksh
$HOME/.shrc for the POSIX Bourne Shell其他人提到了shell标志-i,但这不能用于可靠的编程。POSIX既不要求set -i工作,也不要求$-包含用于交互式shell的i。POSIX只是要求sh -i将外壳强制进入交互模式。
因为变量$PS1可以从环境中导入,所以即使在非交互模式下,它也可能有一个值。在任何非交互式shell中,bash unsets PS1并不是由标准授予的,也不是由任何其他shell执行的。
因此,干净的编程(即使使用bash)是将交互shell的命令放入$HOME/.bashrc中。
https://unix.stackexchange.com/questions/462663
复制相似问题