问题很简单。我想在我的bash脚本中评估PS1
的当前值。
google上的所有资料都指向教程,但是我想评估它是如何通过我当前的终端,或者至少通过某些终端呈现的。
是否有任何软/功能可以帮助我实现这一目标?当然我想要评估所有转义字符,所以echo $PS1
在我的情况下没那么有用。
答案 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以进行进一步处理。
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
下,然后粘贴鼠标中键。脚本命令的标准输出将包含非常相似的内容。
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>
\[
中的\]
或PS1
字符串将分别打印为\1
/ \2
。您可以删除tr -d '\1\2' <<< "$expanded_PS1"
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 Manual的Shell 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 answer的Echo 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