How to set a conditional newline in PS1?

前端 未结 3 1104
感动是毒
感动是毒 2020-12-31 05:25

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

Suppose export PS1=\"\\h:\\W \\u

相关标签:
3条回答
  • 2020-12-31 06:05

    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_COMMAND is a special bash variable which is executed every time before the prompt is set.
    • You need to use the -z flag to check if the length of a string is 0.
    0 讨论(0)
  • 2020-12-31 06:15

    2018 Update (inspired by chepner's answer)

    UPDATE: Fixed PROMPT_COMMAND issues caused by other answers

    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)

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

    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

    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:

    1. Comment out any modifications to PROMPT_COMMAND in your config files (.bash_profile etc.)
    2. Add INIT_PROMPT_COMMAND="$PROMPT_COMMAND" to your config file

    Now open a new 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.

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

    0 讨论(0)
  • 2020-12-31 06:23

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

    In your .bashrc or .bash_profile file, do

    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, PS1 initially does not display a new-line before the prompt. However, PROMPT_CTR is immediately decremented to -1 (it is implicitly 0 before) before the prompt is shown the first time. After the first command, PROMPT_COMMAND clears itself and the counter before resetting the prompt to include the new-line. Subsequently, no PROMPT_COMMAND will execute.

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

    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
      }'
    
    0 讨论(0)
提交回复
热议问题