如何打印当前的bash提示符?

时间:2014-03-11 10:24:51

标签: bash prompt ps1

问题很简单。我想在我的bash脚本中评估PS1的当前值。

google上的所有资料都指向教程,但是我想评估它是如何通过我当前的终端,或者至少通过某些终端呈现的。

是否有任何软/功能可以帮助我实现这一目标?当然我想要评估所有转义字符,所以echo $PS1在我的情况下没那么有用。

6 个答案:

答案 0 :(得分:4)

使用script实用程序(ubuntu上bsdutils包的一部分)的另一种可能性:

$ 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
<prints the formatted prompt properly here>

script命令生成指定的文件&amp;输出也显示在stdout上。如果省略filename,则会生成一个名为typescript的文件。

由于在这种情况下我们对日志文件不感兴趣,因此将filename指定为/dev/null。而是将脚本命令的stdout传递给awk以进行进一步处理。

  1. 整个代码也可以封装成一个函数。
  2. 此外,输出提示也可以分配给变量。
  3. 此方法还支持解析PROMPT_COMMAND ...
  4. 修改
    新版script似乎与打字稿中的管道stdin相呼应。为了解决这个问题,可以将上述机制更改为:

    $ 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
    
    <prints the formatted prompt properly here>
    

    <强>解释

    尝试在终端上手动输入这些命令。将这些命令原样复制到heredoc下,然后粘贴鼠标中键。脚本命令的标准输出将包含非常相似的内容。

    e.g。在上面的例子中,script命令的输出给出了:

    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
    

    使用&#34; some_random_string_here_that_is_not_part_of_PS1&#34;将该stdout拆分as delimiter(记录awk的分隔符)并打印最后一条记录。

    <强> EDIT2:

    另一种机制(使用bash源代码和gdb):

    $ gdb -batch -p $$ -ex 'call bind_variable("expanded_PS1", decode_prompt_string (get_string_value ("PS1")), 0)'
    $ echo "$expanded_PS1"
    <prints the formatted prompt properly here>
    
    1. 虽然这里有一个小问题。 \[中的\]PS1字符串将分别打印为\1 / \2。您可以删除tr -d '\1\2' <<< "$expanded_PS1"
    2. 的内容
    3. 如果您收到gdb无法附加到流程的错误(似乎在ubuntu中发生: - \),请使用gdb运行sudo

答案 1 :(得分:3)

另一种方法是eval回显你的提示以处理任何扩展(不知道为什么括号仍然存在)。这很可能不如@ anishsane的方法强大,但可能会更快一些:

show-prompt() {
    eval 'echo -en "'$PS1'"' | sed -e 's#\\\[##g' -e 's#\\\]##g'
}
# To show it in a function registered with `complete -F` on
# a single tab, and keep the user's input:
show-prompt
echo -n "${COMP_WORDS[@]}"

对此GitHub issue进行了修改。

答案 2 :(得分:1)

Bash 4.4+解决方案,使用参数转换作为提示字符串:echo "${PS1@P}"

[adamhotep@tabasco ~/Downloads]$ echo "the prompt is '${PS1@P}'"
the prompt is '[adamhotep@tabasco ~/Downloads]$'
[adamhotep@tabasco ~/Downloads]$ TEST_STRING='\u is dining at \t using \s \V'
[adamhotep@tabasco ~/Downloads]$ echo "${TEST_STRING}"
\u is dining at \t using \s \V
[adamhotep@tabasco ~/Downloads]$ echo "${TEST_STRING@P}"
adamhotep is dining at 21:45:10 using bash 5.0.3
[adamhotep@tabasco ~/Downloads]$ 

Bash Reference ManualShell Parameter Expansion页面上:

  

${parameter@operator}

     

参数转换。扩展是参数值的转换或有关参数本身的信息,具体取决于运算符的值。
  每个运算符都是一个字母:

     
Q    The expansion is a string that is the value of parameter quoted in a
     format that can be reused as input.
E    The expansion is a string that is the value of parameter with backslash
     escape sequences expanded as with the $'...' quoting mechanism.
P    The expansion is a string that is the result of expanding the value of
     parameter as if it were a prompt string (see PROMPTING below).
A    The expansion is a string in the form of an assignment statement or
     declare command that, if evaluated, will recreate parameter with its
     attributes and value.
a    The expansion is a string consisting of flag values representing
     parameter's attributes.
     

如果参数是@*,则将操作依次应用于每个位置参数,并且扩展为结果列表。如果parameter是下标为@*的数组变量,则将操作依次应用于数组的每个成员,并且扩展为结果列表。

(另请参阅问题this answerEcho expanded PS1。)

答案 3 :(得分:0)

尝试以下命令

echo $PS1 | 
sed -e s/'\\d'/"$(date +'%a %b %_d')"/g | 
sed -e s/'\\t'/"$(date +'%T')"/g | 
sed -e s/'\\@'/"$(date +'%r')"/g | 
sed -e s/'\\T'/"$(date +'%r'| awk {'print $1'})"/g | 
sed -e s/'\\e'//g | sed -e s/'\\h'/"$HOSTNAME"/g | 
sed -e s/'\\h'/"$HOSTNAME"/g | 
sed -e s/'\\H'/"$HOSTNAME"/g | 
sed -e s/'\\u'/"$USER"/g | 
sed -e s@'\\W'@"$(pwd)"@g | 
sed -e s/'\\w'/"$(pwd | sed -e s@$HOME@'~'@g )"/g | 
sed -e s/"\\\\"//g | 
sed -e s/"\\["//g | 
sed -e s/"\\]"/*/g | 
cut -d'*' -f2 | 
cut -d';' -f2 | 
sed s/\ //g | 
sed -e s/[a-z]$/"$([ "$USER" != "root" ] && echo \$ || echo \#)"/g

答案 4 :(得分:0)

我会这样:

echo $PS1

然后使用编辑器对其进行编辑。之后进行测试(在会话处于活动状态时设置):

PS1='\[\033[1m\]\[\033[34m\]\u\[\033[90m\]@\[\033[01;35m\]\h:\[\033[01;32m\]\W\[\033[0m\]$ '

(\ u是用户,\ h是主机,\ w是完整路径,\ W是短路径)

如果我喜欢它,可以通过更改〜/ .bashrc

中的 PS1 的值来使其永久存在

P.S。

如果要查看所有全局变量:

printenv

或:

printenv <name_of_var_to_see>

答案 5 :(得分:-1)

编辑/ etc / bashrc文件

您可以将此作为示例并检查输出

    # If id command returns zero, you’ve root access.
if [ $(id -u) -eq 0 ];
then # you are root, set red colour prompt
  PS1="\\[$(tput setaf 1)\\]\\u@\\h:\\w #\\[$(tput sgr0)\\]"
else # normal
  PS1="[\\u@\\h:\\w] $"
fi