How to print current bash prompt?

后端 未结 6 1051
隐瞒了意图╮
隐瞒了意图╮ 2020-12-15 08:20

The question is simple. I want to evaluate current value of PS1 in my bash script.

All materials on google point to tutorials on pimping it up, but I wa

6条回答
  •  北海茫月
    2020-12-15 08:54

    One more possibility, using script utility (part of bsdutils package on ubuntu):

    $ TEST_PS1="\e[31;1m\u@\h:\n\e[0;1m\$ \e[0m"
    $ RANDOM_STRING=some_random_string_here_that_is_not_part_of_PS1
    $ script /dev/null <<-EOF | awk 'NR==2' RS=$RANDOM_STRING
    PS1="$TEST_PS1"; HISTFILE=/dev/null
    echo -n $RANDOM_STRING
    echo -n $RANDOM_STRING
    exit
    EOF
    
    

    script command generates a file specified & the output is also shown on stdout. If filename is omitted, it generates a file called typescript.

    Since we are not interested in the log file in this case, filename is specified as /dev/null. Instead the stdout of the script command is passed to awk for further processing.

    1. The entire code can also be encapsulated into a function.
    2. Also, the output prompt can also be assigned to a variable.
    3. This approach also supports parsing of PROMPT_COMMAND...

    EDIT:
    It appears that the new version of script echoes the piped stdin in the typescript. To handle that, the above mechanism can be changed to:

    $ TEST_PS1="\e[31;1m\u@\h:\n\e[0;1m\$ \e[0m"
    $ RANDOM_STRING=some_random_string_here_that_is_not_part_of_PS1
    $ script /dev/null <<-EOF | awk '{old=current; current=$0;} END{print old}' RS=$RANDOM_STRING
    PS1="$TEST_PS1"; HISTFILE=/dev/null
    alias $RANDOM_STRING=true
    $RANDOM_STRING
    $RANDOM_STRING
    EOF
    
    
    

    Explanation:

    Try entering these commands manually on the terminal. Copy these commands under the heredoc as they are and paste with mouse middle click. The script command's stdout would contain something very similar.

    e.g. With above case, the output of the script command gives this:

    PS1="\e[31;1m\u@\h:\n\e[0;1m$ \e[0m"; HISTFILE=/dev/null
    alias some_random_string_here_that_is_not_part_of_PS1=true
    some_random_string_here_that_is_not_part_of_PS1
    some_random_string_here_that_is_not_part_of_PS1
     \e[0m"; HISTFILE=/dev/nullhsane-dev : ~/Desktop $ PS1="\e[31;1m\u@\h:\n\e[0;1m$ 
    anishsane@anishsane-dev:
    $ alias some_random_string_here_that_is_not_part_of_PS1=true
    anishsane@anishsane-dev:
    $ some_random_string_here_that_is_not_part_of_PS1
    anishsane@anishsane-dev:
    $ some_random_string_here_that_is_not_part_of_PS1
    anishsane@anishsane-dev:
    $ exit
    

    Split that stdout with "some_random_string_here_that_is_not_part_of_PS1" as delimiter (record separator of awk) and print the last but one record.

    EDIT2:

    Another mechanism (using bash source code and gdb):

    $ gdb -batch -p $$ -ex 'call bind_variable("expanded_PS1", decode_prompt_string (get_string_value ("PS1")), 0)'
    $ echo "$expanded_PS1"
    
    
    1. There is a tiny issue here though. The \[ or \] strings in PS1 will get printed as \1/\2 respectively. You can remove those with tr -d '\1\2' <<< "$expanded_PS1"
    2. If you get error like gdb failed to attach to the process (seems to happen in ubuntu :-\ ), run gdb with sudo.

提交回复
热议问题