如何打印当前bash提示符?

问题描述 投票:10回答:6

这个问题很简单。我想在我的bash脚本,以评估PS1的电流值。

对谷歌一点,所有的材料教程上拉皮条它,但我要评估,看看如何将它被我现在的终端至少通过一些终端呈现,或。

是否有任何软/功能,将帮助我做到这一点?当然,我想都逃脱评测的字符,所以echo $PS1是不是在我的情况下是有用的。

bash prompt ps1
6个回答
4
投票

击4.4+溶液使用参数变换为提示字符串:echo "${PS1@P}"

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

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.

如果参数是@*,操作被施加到反过来每个位置参数,和扩展为结果的列表。如果参数是@*下标数组变量,该操作被应用于反过来阵列的每个成员,并且膨胀为结果的列表。

(参见从重复的问题this answer Echo expanded PS1。)

的Z shell(zsh)可以用${(%%)PS1}或与其print内置的-P标志做到这一点:

[adamhotep@tabasco ~]% echo "the prompt is '${(%%)PS1}'"
the prompt is '[adamhotep@tabasco ~]%'
[adamhotep@tabasco ~]% print -P "the prompt is '$PS1'"
the prompt is '[adamhotep@tabasco ~]%'
[adamhotep@tabasco ~]% TEST_STRING="%n is dining at %* using %N $ZSH_VERSION"
[adamhotep@tabasco ~]% echo "$TEST_STRING"
%n is dining at %* using %N 5.7.1
[adamhotep@tabasco ~]% echo "${(%%)TEST_STRING}"
adkatz is dining at 11:49:01 using zsh 5.7.1
[adamhotep@tabasco ~]% print -P "$TEST_STRING"
adkatz is dining at 11:49:07 using zsh 5.7.1
[adamhotep@tabasco ~]% 

Zsh Expansion and Subsitution手册告诉我们:

Parameter Expansion Flags。如果开口撑杆直接跟着一个左括号,字符串直到匹配的右括号将作为标志的列表。在重复一个标志是有意义的情况下,重复不必是连续的;例如,(q%q%q)意味着同样的事情更易读(%%qqq)。将支持以下标志: ...

%展开全部在相同的方式中的提示所得到的话%逸出(见Prompt Expansion)。如果这个标志出现两次,充分提示扩张对得到的话做了,这取决于的PROMPT_PERCENTPROMPT_SUBSTPROMPT_BANG选项的设置。

Zsh Builtinsprint文档:

-P执行提示膨胀(参见Prompt Expansion)。与-f组合,提示转义序列仅内插参数解析,而不是格式字符串内。


4
投票

一个更可能性,使用script实用程序(bsdutils包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
<prints the formatted prompt properly here>

script命令生成指定的文件&输出也被示出在stdout。如果省略文件名,它会生成一个名为打字稿文件。

因为我们不感兴趣,在这种情况下,日志文件,文件名被指定为/dev/null。取而代之的是脚本命令的标准输出被传递到awk中作进一步处理。

  1. 整个代码也可以被封装到功能。
  2. 此外,输出提示也可被分配给一个变量。
  3. 这种方法还支持PROMPT_COMMAND的解析......

编辑: 看来,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下,这些命令复制。脚本命令的stdout将包含一些非常相似。

例如与上述的情况下,脚本命令的输出给出了这样的:

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

斯普利特以“some_random_string_here_that_is_not_part_of_PS1”作为分隔符(AWK的记录分隔符)标准输出和打印,但最后一个记录。

Aaditi:

另一种机制(使用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. 如果你得到错误,如gdb未能附加到该进程(似乎在Ubuntu发生: - \),运行与gdb sudo

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


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

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>

-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
© www.soinside.com 2019 - 2024. All rights reserved.