开源软件的一个伟大优势是其源代码是公开的 :-)
Bash本身不提供此功能,但您可以使用各种技巧来提供子集(例如将\u
替换为$USER
等)。但是,这需要大量的功能复制,并确保代码与未来的bash
同步。
如果您想获得提示变量的全部功能(并且您不介意通过一些编码来实现(如果您介意,那你为什么会在这里呢?)),那么将其添加到shell本身就很容易。
如果您下载bash
的代码(我正在查看版本4.2),则有一个y.tab.c
文件,其中包含decode_prompt_string()
函数:
char *decode_prompt_string (string) char *string; { ... }
这是用于评估提示的
PSx
变量的函数。为了让此功能可以提供给shell本身的用户(而不仅仅是被shell使用),您可以按照以下步骤添加内部命令
evalps1
。
首先,更改
support/mkversion.sh
,以便不会将其与“真正的”
bash
混淆,并且FSF可以否认所有保证方面的知识 :-) 。只需更改一行即可(我添加了
-pax
):
echo "#define DISTVERSION \"${float_dist}-pax\""
其次,修改builtins/Makefile.in
以添加一个新的源文件。这需要执行多个步骤。
(a) 将$(srcdir)/evalps1.def
添加到DEFSRC
的末尾。
(b) 将evalps1.o
添加到OFILES
的末尾。
(c) 添加所需的依赖项:
evalps1.o: evalps1.def $(topdir)/bashtypes.h $(topdir)/config.h \
$(topdir)/bashintl.h $(topdir)/shell.h common.h
第三步,添加 builtins / evalps1.def
文件本身,这是运行 evalps1
命令时执行的代码:
This file is evalps1.def, from which is created evalps1.c.
It implements the builtin "evalps1" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http:
$PRODUCES evalps1.c
$BUILTIN evalps1
$FUNCTION evalps1_builtin
$SHORT_DOC evalps1
Outputs the fully interpreted PS1 prompt.
Outputs the PS1 prompt, fully evaluated, for whatever nefarious purposes
you require.
$END
#include <config.h>
#include "../bashtypes.h"
#include <stdio.h>
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
int
evalps1_builtin (list)
WORD_LIST *list;
{
char *ps1 = get_string_value ("PS1");
if (ps1 != 0)
{
ps1 = decode_prompt_string (ps1);
if (ps1 != 0)
{
printf ("%s", ps1);
}
}
return 0;
}
其中大部分是GPL许可证(因为我从exit.def
中进行了修改),在末尾有一个非常简单的函数来获取和解码PS1
。
最后,在顶层目录中构建这个东西即可:
./configure
make
bash
可执行文件可以重命名为paxsh
,但我怀疑它永远不会像其祖先一样普及 :-)
运行它,你就可以看到它的效果:
pax> mv bash paxsh
pax> ./paxsh --version
GNU bash, version 4.2-pax.0(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pax> ./paxsh
pax> echo $BASH_VERSION
4.2-pax.0(1)-release
pax> echo "[$PS1]"
[pax> ]
pax> echo "[$(evalps1)]"
[pax> ]
pax> PS1="\h: "
paxbox01: echo "[$PS1]"
[\h: ]
paxbox01: echo "[$(evalps1)]"
[paxbox01: ]
当您将PSx
变量放入提示符中时,回显$PS1
只会给出变量,而evalps1
命令将评估它并输出结果。
诚然,对bash
进行代码更改以添加内部命令可能被一些人认为是过度的,但如果您想要完美评估PS1
,这肯定是一个选项。
\ u
扩展为username
的内容,那就很容易了。但它没有记录(我不知道足够的C语言来挖掘Bash)。 - l0b0subst.c
文件中的expand_prompt_string
。现在要弄清楚如何从脚本内部调用它... - l0b0\u
这样的额外指令。而且...我不确定expand_prompt_string是否可以从shell中访问,除非你打补丁。(也许你可以单独编译它...) - Cascabel