Un grande vantaggio del software open source è che la fonte è, beh, aperto :-)
Se si scarica il codice per bash
(sto guardando versione 4.2), c'è un file che contiene y.tab.c
la funzione decode_prompt_string()
:.
char *decode_prompt_string (string) char *string; { ... }
si può cercare di estrarre che (insieme a qualsiasi routine di supporto necessarie e costruire un eseguibile, che ha fatto il lavoro per voi Anche se, da una prova superficiale, queste routine di supporto sembrano essere molto , quindi potrebbe essere difficile.
Oltre a questo, probabilmente si può "ingannare" bash
in espansione per voi con qualcosa di simile:
expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1
| grep xyzzyplughtwisty
| head -1
| sed 's/xyzzyplughtwisty//g')
Ora ho messo che su più righe per facilitarne la lettura, ma è stato fatto su un linea.
Ciò che fa è eseguire un'istanza interattiva di bash
, passando (che si spera sia) un comando non valido.
Poiché è interattivo, stampa il prompt in modo da afferrare la prima riga con la stringa di comando su di esso e rimuovere quella stringa di comando. Ciò che rimane dovrebbe essere il prompt.
Sul mio sistema, questo è ciò che ottengo:
pax> expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1 | grep xyzzyplughtwisty | head -1 | sed 's/xyzzyplughtwisty//g')
pax> echo "[$expPS1]"
[pax> ]
pax>
Tuttavia, questo ha problemi con multi-linea di prompt e sarà effettivamente dare il prompt regolare, piuttosto che quello attuale shell.
Se si desidera farlo correttamente, può comportare l'aggiunta di un po 'per bash
sé. Ecco i passaggi per aggiungere un comando interno evalps1
.
In primo luogo, cambiare support/mkversion.sh
in modo che non si confonderlo con un "vero" bash
, e in modo che la FSF può negare tutta la conoscenza ai fini della garanzia :-) semplicemente cambiare una riga (ho aggiunto il bit -pax
):
In secondo luogo, modificare `builtins/Makefile.in per aggiungere un nuovo file sorgente. Ciò comporta una serie di passaggi.
(a) Aggiungere $(srcdir)/evalps1.def
alla fine di DEFSRC
.
(b) Aggiungere evalps1.o
alla fine di OFILES
.
(c) Aggiungere le dipendenze richieste:
evalps1.o: evalps1.def $(topdir)/bashtypes.h $(topdir)/config.h \
$(topdir)/bashintl.h $(topdir)/shell.h common.h
In terzo luogo, aggiungere il file builtins/evalps1.def
stesso, questo è il codice che viene eseguito quando si esegue il comando 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://www.gnu.org/licenses/>.
$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;
}
Il grosso di questo è la licenza GPL (poiché l'ho modificata da exit.def
) con una funzione molto semplice alla fine per ottenere e decodificare PS1
.
Infine, solo costruire la cosa nella directory di livello superiore:
./configure
make
Il bash
che appare può essere rinominato paxsh
, anche se dubito che sarà mai diventare così diffuso come il suo antenato :-)
E in esecuzione, è possibile vedere in azione:
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: ]
Ora, concesso, facendo modifiche al codice per bash
per aggiungere un n comando interno può essere considerato eccessivo da alcuni, ma, se si desidera una valutazione accurata di PS1
, è certamente un'opzione.
Forse altre persone lo sanno, ma non ho idea di cosa tu stia parlando. Cosa stai cercando di realizzare? – Kurt
Vuoi valutare $ PS1, $ PS2? O vuoi attribuire valori a quelle variabili all'interno del tuo script? – Gangadhar
Supponiamo che ci sia una funzione o comando chiamato 'evaluate'. Quale dovrebbe essere il risultato di 'valutare PS1'? –