"${debian_chroot:+($debian_chroot)}" 在我的终端提示符中是什么作用?

在我的.bashrc文件中,我终端提示符的定义中,除了其他内容外,我有这段代码片段:
${debian_chroot:+($debian_chroot)}

这是做什么的,我需要它吗?
4个回答

回答这个问题的重要部分在于从/etc/bash.bashrc中提取的这段代码:

if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

这意味着如果变量$debian_chroot为空,并且文件/etc/debian_chroot存在且可读,则将变量设置为文件的内容。
现在这是用来做什么的呢?当你在一个Debian系统内部有另一个Debian系统的chroot时(Ubuntu是基于Debian的),文件/etc/debian_chroot就会出现。所以这是为了更好地进行概览,在chroot环境中还是不在其中可以加以区分。
例如,当你在/srv/nfs4/netboot/中有另一个系统的chroot时,你可以在/srv/nfs4/netboot/etc/debian_chroot中设置这个chroot的名称(在我的例子中,它是一个nfs4 pxe netboot驱动)。
user@host:~# echo "netboot" >/srv/nfs4/netboot/etc/debian_chroot

然后当你进入chroot时:
chroot /srv/nfs4/netboot/

您的提示看起来像这样:
(netboot)user@host:~#

通常,${var:+value} 的意思是:
if $var is defined and not null; then use 'value'; else do nothing

debian_chroot变量在/etc/bash.bashrc文件中定义。如果存在且可读,它将获取/etc/debian_chroot文件的内容。默认情况下,该文件不存在。

更多详细信息,请参见:

现在,为了更好地理解其中发生的事情,请在终端中执行以下操作:

radu@Radu:~$ PS1='${var:+($var)}\u@\h:\w\$ '
radu@Radu:~$ var="test"
                  ----
                   |
  ------------------
  |
  V
(test)radu@Radu:~$ var=""
radu@Radu:~$ var="and so on"
(and so on)radu@Radu:~$

如果环境变量$debian_chroot存在且不为空,则将${debian_chroot:+($debian_chroot)}替换为($debian_chroot)(即带有括号的$debian_chroot的值)。 $debian_chroot/etc/bash.bashrc中设置为/etc/debian_chroot的内容(默认情况下该文件不存在),并且$debian_chroot尚未具有值。 ${debian_chroot:+($debian_chroot)}通常用于定义Bash提示符,例如。
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

根据名字,您可以使用这个变量来指示您所在的chroot,方法是将etc/debian_chroot放置在chroot根文件夹中。
如果您不知道什么是chroot,那么很可能您不需要它;-) 但您仍然可以滥用它,将其他一些信息包含到您的Bash提示符中。
默认情况下,它不做任何操作。

如果你从来不需要使用debian_chroot,那么这是一个方便的地方,可以通过以下方式将命令提示符显示的时间放在这里:
export PROMPT_COMMAND='debian_chroot=$(date +%r)'

在终端中输入以下命令,观察您的命令提示符随时间变化:
rick@alien:~$ export PROMPT_COMMAND='debian_chroot=$(date +%r)'

(09:14:59 PM)rick@alien:~$ 

设置一次时间后,要获得每秒更新的运行时钟,请使用以下代码:
while sleep 1;do tput sc;tput cup $(($(tput lines)-1)) 1;printf `date +%r`;tput rc;done &

2虽然这样做是可以的,但有点奇怪。为什么不在自定义的$PS1中使用一个更合适的变量名呢? - Adam Katz
@AdamKatz 当一行超出终端宽度并换行时,它将无法工作。然后您将无法使用向上箭头正确地调用它。我实际上是想对其进行微调,但时间不够了。我不确定您所说的“更合适的变量名称”是什么意思? - WinEunuuchs2Unix
安全包装需要在控制字符周围添加\[\](或\001\002)。Debian中的默认bash提示符会自动完成这一操作,但是您的tput命令可能会破坏它。这与我的评论无关,在我的评论中,我建议在~/.bashrc中定义$PS1时使用一个单独的变量。 - Adam Katz
如果你想在提示符中添加时间,请考虑使用export PS1="(\t)$PS1",其中\t\@如bash(1)手册的PROMPTING部分所述。请注意,这不能处理像%r这样的strftime字符串,因此你可以选择使用export PS1="($now)$PS1" PROMPT_COMMAND='now=$(date +%r)',这将保留Debian chroot指示器。 - Adam Katz