Bill Daugherty Asked: 2019-10-30 10:23:14 +0800 CST2019-10-30 10:23:14 +0800 CST 2019-10-30 10:23:14 +0800 CST 如何获得提示的长度? 772 有没有办法可以确定提示的长度?有没有一种方法可以查看PS1变量并从中获取长度并重复相同长度的字符? 我正在尝试为 bash 命令创建一个新的终端提示符。 bash prompt 1 个回答 Voted Best Answer Kamil Maciorowski 2019-10-30T11:36:43+08:002019-10-30T11:36:43+08:00 如果你PS1写得很好,那么它将非打印片段包含在\[ \]. 您需要首先摆脱这些碎片。通常我会使用sed,但我不认为可以轻松地进行非贪婪匹配sed,因此perl: perl -pe 's|\\\[.*?\\\]||g' <<<"$PS1" 里面的换行符\[ \]不会perl删除片段。这不应该发生在 wellwritten PS1,所以这不是问题。 您需要一个辅助变量中的结果: ps="$(perl -pe 's|\\\[.*?\\\]||g' <<<"$PS1")" 需要一个单独的变量,因为下一步是要求 Bash 评估字符串,就好像它是一个提示一样;使用变量很容易。 不过有一件事:这里的字符串 ( <<<) 广告一个尾随换行符,然后命令替换 ( $( )) 删除所有尾随换行符。如果最初没有换行符,那么这两种现象将相互抵消。如果有尾随换行符,那么您将全部丢失,最终结果将以未知数关闭。在一般情况下,我们可以通过附加后缀(这里)来处理这个问题X: ps="$(perl -pe 's|\\\[.*?\\\]||g' <<<"${PS1}X")" 这样,两种机制肯定会相互抵消。然后,您可以将其视为提示进行评估,如下所示: printf '%s' "${ps@P}" 无论如何你都需要长度,所以printf不是完全必要的: wc -m <<<"${ps@P}" 我认为wc -m比wc -c在这种情况下要好。由于我们的后缀(长度为 1)和另一个额外的换行符(from <<<),结果被夸大了。因此,您需要减去 2。 整个过程作为一个函数: plen () { local ps len ps="$(perl -pe 's|\\\[.*?\\\]||g' <<<"${PS1}X")" len="$(wc -m <<<"${ps@P}")" printf '%s\n' "$((len-2))" } 你说你想 重复相同长度的字符 也许你不需要长度。 pblock () { local ps ps="$(perl -pe 's|\\\[.*?\\\]||g' <<<"${PS1}X")" ps="${ps@P}" printf '%s' "${ps::-1}" | tr -c '\n\r' 'M' } 这个函数会复制提示的形状,即使它是多行的,虽然像 tab 这样的字符很麻烦。根据您的tr多字节字符(例如ś),也可能使该功能无法按预期工作。 你可能更喜欢也可能不喜欢printf '%s\n' …。
如果你
PS1
写得很好,那么它将非打印片段包含在\[ \]
. 您需要首先摆脱这些碎片。通常我会使用sed
,但我不认为可以轻松地进行非贪婪匹配sed
,因此perl
:里面的换行符
\[ \]
不会perl
删除片段。这不应该发生在 wellwrittenPS1
,所以这不是问题。您需要一个辅助变量中的结果:
需要一个单独的变量,因为下一步是要求 Bash 评估字符串,就好像它是一个提示一样;使用变量很容易。
不过有一件事:这里的字符串 (
<<<
) 广告一个尾随换行符,然后命令替换 ($( )
) 删除所有尾随换行符。如果最初没有换行符,那么这两种现象将相互抵消。如果有尾随换行符,那么您将全部丢失,最终结果将以未知数关闭。在一般情况下,我们可以通过附加后缀(这里)来处理这个问题X
:这样,两种机制肯定会相互抵消。然后,您可以将其视为提示进行评估,如下所示:
无论如何你都需要长度,所以
printf
不是完全必要的:我认为
wc -m
比wc -c
在这种情况下要好。由于我们的后缀(长度为 1)和另一个额外的换行符(from<<<
),结果被夸大了。因此,您需要减去 2。整个过程作为一个函数:
你说你想
也许你不需要长度。
这个函数会复制提示的形状,即使它是多行的,虽然像 tab 这样的字符很麻烦。根据您的
tr
多字节字符(例如ś
),也可能使该功能无法按预期工作。你可能更喜欢也可能不喜欢
printf '%s\n' …
。