2012-04-08 14 views
8

可能性の重複:
Echo expanded PS1bash:PS1、PS2、...の評価方法

はbashスクリプト内からPS1PS2などを '評価' する方法はありますか?

私は現在のPS1のすべての要素を取得するために代替手段を使用できますが、これらの代替手段を使用する代わりに、その定義を再利用できるようにしたいと考えています。例えば

===================================== 
PS1 element -->  Alternate means 
===================================== 
\u   -->  $USER 
\h   -->  $HOSTNAME 
\w   -->  $PWD 
... 
===================================== 

私は非常によく私のスクリプトに「代替手段」列を使用することができますが、私はしたくありません。私のPS1では、例えば、私はPS1を評価することによって単純に再利用できるようにするために、ターミナルのエスケープシーケンスを使って太い青色を使用しています。

+0

おそらく他の人が知っているかもしれませんが、私はあなたが何を話しているのか分かりません。あなたは何を達成しようとしていますか? – Kurt

+0

$ PS1、$ PS2を評価しますか?または、スクリプト内の変数に値を属性付けしますか? – Gangadhar

+0

'evaluate'という関数やコマンドがあるとします。 'PS1の評価'の結果はどうあるべきですか? –

答えて

10

オープンソースソフトウェアの一つの大きな利点は、あなたが(私はバージョン4.2で探しています)、含まれていy.tab.cファイルがありますbash用のコードをダウンロードする場合、ソースは、よく、オープン:-)

であるということですdecode_prompt_string()機能:

char *decode_prompt_string (string) char *string; { ... } 

あなたは(一緒にとのいずれかがサポートルーチンを必要とすることを抽出して、あなたのために仕事をした実行ファイルをビルドしようとすることができぞんざいな試みから、これらのサポートルーチンがたくさんあるように見える、けれども。 、これは難しい作業かもしれません。

それ以外は

、あなたはおそらくのようなもので、あなたのためにそれを拡大するに「トリック」bashことができます。

expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1 
     | grep xyzzyplughtwisty 
     | head -1 
     | sed 's/xyzzyplughtwisty//g') 

は今、私は読みやすくするために、複数行に渡って置かれているが、それは、一つに行われましたライン。

これは、無効なコマンドを渡す(うまくいけば)bashのインタラクティブなインスタンスを実行します。

対話型なので、プロンプトが表示されるので、最初の行にコマンド文字列をつけて、コマンド文字列を削除します。残されているのはプロンプトです。

pax> expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1 | grep xyzzyplughtwisty | head -1 | sed 's/xyzzyplughtwisty//g') 

pax> echo "[$expPS1]" 
[pax> ] 

pax> 

しかし、これは、実際に現在のシェル1のではなく、あなたの通常のプロンプトを与えるプロンプト複数行に問題があります。私のシステムで

が、これは私が得るものです。


あなたはそれが正しく、は、それ自体bashに少し追加伴うこと行いたい場合は

。次に、内部コマンドevalps1を追加する手順を示します。

まず、あなたがbash「本物」と混同しないであろう、とFSFは、単に1行を変更:-)保証の目的のために、すべての知識を拒否することができるようにというように(私は-paxビットを追加しました)support/mkversion.shを変更します。

echo "#define DISTVERSION \"${float_dist}-pax\"" 

次に、 `builtins/Makefile.in 'を変更して新しいソースファイルを追加します。これにはいくつかのステップが必要です。

(a)DEFSRCの末尾に$(srcdir)/evalps1.defを追加します。

(b)evalps1.oOFILESの末尾に追加します。

(c)に必要な依存関係を追加します。

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; 
} 

バルク:

evalps1.o: evalps1.def $(topdir)/bashtypes.h $(topdir)/config.h \ 
      $(topdir)/bashintl.h $(topdir)/shell.h common.h 

第三に、builtins/evalps1.defファイル自体を追加し、これはあなたがevalps1コマンドを実行したときに実行されますコードですそのうちGPLライセンス(exit.defから変更したものです)は最後に非常に単純な関数で、PS1を取得してデコードします。

最後に、ちょうどトップレベルのディレクトリにものを構築する:

./configure 
make 

私はそれが今まで

:-)その祖先と同じくらい普及しないだろうけれども表示されますが、paxshに名前を変更することができbash

そして、それを実行している、あなたはアクションでそれを見ることができます。今すぐ

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: ] 

、付与された、追加するbashにコードの変更を行いますいくつかの内部コマンドは過剰なものと見なされるかもしれませんが、正確な評価がPS1の場合は、確かにオプションです。

+0

あなたのシステムでそれを試してもよろしいですか?私が$ expPS1を試してみたところ、値として "bash::command not found ..."が得られました。また、複数行のプロンプトが表示されている場合は、先頭-1が機能しないことに注意してください。また、プロンプトを太字で表示しています。これが私がこの質問を投稿した理由です。PS1をどんな形や形でも複製することなく完全に保持したいと思います。 Fyi、私のPS1は次のように設定されています: '\ [\ 033 [0; 34m \] \ u @ \ h $? \ w \ n $ \ [\ 033 [0m \] ''。私はあなたのソリューションの創意工夫が間違いありませんが、それは非常に遅いです:私はすべての結果を見る前に1-2秒のギャップがあります。 – Harry

+0

それはあなたが持っている問題のかなり洗濯物のリストです:-)(1)はい、私のシステムで試しました、その最後のビットは実際の転写物です。 (2)はい、 'head -1'は複数行のプロンプトでは機能しませんが、あなたはそれをもっと巧妙にする必要があります。おそらく、行数や' PS1'の前処理の予知が必要でしょう'\ n'セクション。 (3) 'TERM'設定を強制しなければならないかもしれないが、問題の色は何か分かりません。 (4)速度を保証することはできません。それはシェルを起動するのにかかる時間に依存します。 2番目の解決策が不十分な場合は、最初のものを見る必要があります。 – paxdiablo

+0

しかし、私はそれが少なくともそのような問題を解決すべきだが、それはもっと努力しているかもしれないと思う。任意の 'PS1'を翻訳するために、Cコードと同様のことをするスクリプトを書くことさえできます。 – paxdiablo