bash 如何在 PS1 中设置条件换行符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14859148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:33:21  来源:igfitidea点击:

How to set a conditional newline in PS1?

bashshellps1

提问by Ali

I am trying to set PS1so that it prints out something just right after login, but preceded with a newline later.

我正在尝试进行设置,PS1以便在登录后立即打印出一些内容,但稍后以换行符开头。

Suppose export PS1="\h:\W \u\$ ", so first time (i.e., right after login) you get:

假设export PS1="\h:\W \u\$ ",所以第一次(即登录后)你得到:

hostname:~ username$ 

I've been trying something like in my ~/.bashrc:

我一直在尝试类似的东西~/.bashrc

function __ps1_newline_login {
  if [[ -n "${PS1_NEWLINE_LOGIN-}" ]]; then
    PS1_NEWLINE_LOGIN=true
  else
    printf '\n'
  fi
}

export PS1="$(__ps1_newline_login)\h:\W \u$ “

expecting to get:

期望得到:

# <empty line>
hostname:~ username$ 

A complete example from the the beginning would be:

一开始的完整示例是:

hostname:~ username$ ls `# notice: no empty line desired above!`
Desktop      Documents

hostname:~ username$ 

采纳答案by dogbane

Try the following:

请尝试以下操作:

function __ps1_newline_login {
  if [[ -z "${PS1_NEWLINE_LOGIN}" ]]; then
    PS1_NEWLINE_LOGIN=true
  else
    printf '\n'
  fi
}

PROMPT_COMMAND='__ps1_newline_login'
export PS1="\h:\W \u$ "

Explanation:

解释:

  • PROMPT_COMMANDis a special bash variable which is executed every time before the prompt is set.
  • You need to use the -zflag to check if the length of a string is 0.
  • PROMPT_COMMAND是一个特殊的 bash 变量,每次在设置提示之前都会执行。
  • 您需要使用该-z标志来检查字符串的长度是否为 0。

回答by chepner

Running with dogbane's answer, you can make PROMPT_COMMAND "self-destruct", preventing the need to run a function after every command.

使用 dogbane 的答案运行,您可以使 PROMPT_COMMAND“自毁”,从而无需在每个命令后运行函数。

In your .bashrcor .bash_profilefile, do

在您的.bashrc.bash_profile文件中,执行

export PS1='\h:\W \u$ '
reset_prompt () {
  PS1='\n\h:\W \u$ '
}
PROMPT_COMMAND='(( PROMPT_CTR-- < 0 )) && { 
  unset PROMPT_COMMAND PROMPT_CTR
  reset_prompt
}'

When the file is processed, PS1initially does not display a new-line before the prompt. However, PROMPT_CTRis immediately decremented to -1 (it is implicitly 0 before) before the prompt is shown the first time. After the first command, PROMPT_COMMANDclears itself and the counter before resetting the prompt to include the new-line. Subsequently, no PROMPT_COMMANDwill execute.

处理文件时,PS1最初在提示前不显示换行符。但是,PROMPT_CTR在第一次显示提示之前立即递减为 -1(之前隐式为 0)。在第一个命令之后,PROMPT_COMMAND在重置提示以包含换行符之前清除自身和计数器。随后, noPROMPT_COMMAND将执行。

Of course, there is a happy medium, where instead of PROMPT_COMMANDclearing itself, it just resets to a more ordinary function. Something like

当然,有一个快乐的媒介,它不会PROMPT_COMMAND自我清除,而是重置为更普通的功能。就像是

export PS1='\h:\W \u$ '
normal_prompt_cmd () {
   ...
}
reset_prompt () {
  PS1='\n\h:\W \u$ '
}
PROMPT_COMMAND='(( PROMPT_CTR-- < 0 )) && {
   PROMPT_COMMAND=normal_prompt_cmd
   reset_prompt
   unset PROMPT_CTR
  }'

回答by JBallin

2018 Update(inspired by chepner's answer)

2018 更新(灵感来自 chepner 的回答)

UPDATE: Fixed PROMPT_COMMANDissues caused by other answers

更新:修复PROMPT_COMMAND了由其他答案引起的问题

Changes:

变化:

  1. No need to export PS1
  2. I used "\n$PS1" instead of re-typing.
  3. Other answers interfere with the PROMPT_COMMAND's default behavior (more info below)
  1. 无需导出PS1
  2. 我使用了 "\n$PS1" 而不是重新输入。
  3. 其他答案会干扰PROMPT_COMMAND的默认行为(更多信息如下)


Enter the following in ~/.bash_profile (substituting first line with your prompt):

在 ~/.bash_profile 中输入以下内容(用您的提示替换第一行):

PS1=YOUR_PROMPT_HERE

add_newline_to_prompt() {
  is_new_login="true"
  INIT_PROMPT_COMMAND="$PROMPT_COMMAND"
  DEFAULT_PROMPT_COMMAND=update_terminal_cwd
  PROMPT_COMMAND='{
    if [ $is_new_login = "true" ]; then
      is_new_login="false"
      eval $INIT_PROMPT_COMMAND
    else
      PS1="\n$PS1"
      PROMPT_COMMAND=$DEFAULT_PROMPT_COMMAND
    fi
  }'
}

add_newline_to_prompt


PROMPT_COMMAND

PROMPT_COMMAND

I noticed that my tab name in terminal wasn't updating to my current working directory and did some investigating. I realized that above solutions are messing with PROMPT_COMMAND. Try this out:

我注意到我在终端中的选项卡名称没有更新到我当前的工作目录并进行了一些调查。我意识到上述解决方案与PROMPT_COMMAND. 试试这个:

  1. Comment out any modifications to PROMPT_COMMANDin your config files (.bash_profile etc.)
  2. Add INIT_PROMPT_COMMAND="$PROMPT_COMMAND"to your config file
  1. 注释掉PROMPT_COMMAND对配置文件(.bash_profile 等)中的任何修改
  2. 添加INIT_PROMPT_COMMAND="$PROMPT_COMMAND"到您的配置文件

Now open a new shell:

现在打开一个新的shell:

$ echo $INIT_PROMPT_COMMAND
shell_session_history_check; update_terminal_cwd
$ echo $PROMPT_COMMAND
update_terminal_cwd

Notice that when you open a new shell, it runs both a "history check" and updates the name of the tab current working directory. Notice that it only runs the "history check" initially, and then never runs it again.

请注意,当您打开一个新 shell 时,它会运行“历史检查”并更新选项卡当前工作目录的名称。请注意,它最初只运行“历史检查”,然后再也不运行它。

NOTE: I've only tested this on Mac's Terminal. May be different on other systems.

注意:我只在 Mac 的终端上测试过。在其他系统上可能有所不同。