2012-04-08 28 views
8

thể trùng lặp:
Echo expanded PS1bash: Cách đánh giá PS1, PS2, ...?

Có cách nào để 'đánh giá' PS1, PS2, vv từ bên trong một kịch bản bash?

Mặc dù, tôi có thể sử dụng các phương tiện thay thế để nhận tất cả các phần tử hiện tại của mình PS1, tôi thực sự muốn có thể sử dụng lại định nghĩa của nó thay vì sử dụng các phương tiện thay thế này.

Ví dụ,

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

tôi rất tốt có thể sử dụng cột 'có nghĩa là thay thế' trong kịch bản của tôi, nhưng tôi không muốn. Ví dụ, trong ví dụ PS1, tôi sử dụng màu xanh đậm thông qua các chuỗi thoát thiết bị đầu cuối mà tôi muốn có thể đơn giản sử dụng lại bằng cách đánh giá PS1.

+0

Có thể những người khác biết, nhưng tôi không biết bạn đang nói về điều gì. Bạn đang cố gắng để thực hiện? – Kurt

+0

Bạn có muốn đánh giá $ PS1, $ PS2 không? Hoặc bạn có muốn phân bổ các giá trị cho các biến đó bên trong tập lệnh của bạn không? – Gangadhar

+0

Giả sử có một chức năng hoặc lệnh gọi là 'đánh giá'. Kết quả của 'đánh giá PS1' nên là gì? –

Trả lời

10

Một lợi thế lớn của phần mềm mã nguồn mở là nguồn là, tốt, mở :-)

Nếu bạn tải về mã cho bash (Tôi nhìn vào phiên bản 4.2), có một tập tin y.tab.c chứa các decode_prompt_string() chức năng:.

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

bạn có thể cố gắng trích xuất (cùng với bất kỳ thói quen hỗ trợ cần thiết và xây dựng một thực thi mà đã làm công việc cho bạn Mặc dù, từ một thử lướt qua, những thói quen hỗ trợ dường như có rất nhiều , vì vậy đây có thể là một nhiệm vụ khó khăn.


Ngoài ra, bạn có thể có thể "lừa" bash vào mở rộng nó cho bạn với một cái gì đó như:

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

Bây giờ tôi đã đặt mà trên nhiều dòng cho dễ đọc nhưng nó đã được thực hiện trên một hàng.

Điều này thực hiện thao tác tương tác bash, chuyển (lệnh hy vọng) là lệnh không hợp lệ.

Vì nó tương tác, nó in dấu nhắc nên tôi lấy dòng đầu tiên bằng chuỗi lệnh trên đó và xóa chuỗi lệnh đó. Những gì còn lại sẽ là dấu nhắc.

Trên hệ thống của tôi, đây là những gì tôi nhận được:

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

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

pax> 

Tuy nhiên, điều này có vấn đề với nhiều dòng nhắc nhở và thực sự sẽ cung cấp cho bạn thường xuyên nhắc nhở của bạn chứ không phải là một vỏ hiện hành.


Nếu bạn muốn làm điều đó đúng cách, nó có thể bao gồm thêm một chút để bash riêng của mình. Dưới đây là các bước để thêm lệnh nội bộ evalps1.

Thứ nhất, thay đổi support/mkversion.sh để bạn sẽ không nhầm lẫn nó với một "thực" bash, và do đó FSF thể phủ nhận tất cả các kiến ​​thức cho các mục đích bảo hành :-) Đơn giản chỉ cần thay đổi một dòng (tôi thêm chút -pax):

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

Thứ hai, thay đổi `builtins/Makefile.in để thêm tệp nguồn mới. Điều này đòi hỏi một số bước.

(a) Thêm $(srcdir)/evalps1.def vào cuối DEFSRC.

(b) Thêm evalps1.o vào cuối OFILES.

(c) Thêm sự phụ thuộc yêu cầu:

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

Thứ ba, thêm các tập tin builtins/evalps1.def bản thân, đây là đoạn code đó được thực hiện khi bạn chạy evalps1 lệnh:

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

Phần lớn đó là giấy phép GPL (kể từ khi tôi sửa đổi nó từ exit.def) với một chức năng rất đơn giản ở cuối để có được và giải mã PS1.

Cuối cùng, chỉ cần xây dựng các điều trong thư mục cấp cao nhất:

./configure 
make 

Các bash xuất hiện có thể được đổi tên thành paxsh, mặc dù tôi nghi ngờ nó bao giờ sẽ trở nên phổ biến như tổ tiên của nó :-)

Và chạy nó, bạn có thể nhìn thấy nó trong hành động:

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

Bây giờ, cấp, làm thay đổi mã để bash để thêm một n lệnh nội bộ có thể được coi là overkill bởi một số nhưng, nếu bạn muốn có một đánh giá chính xác của PS1, nó chắc chắn là một lựa chọn.

+0

Bạn có chắc chắn đã thử trên hệ thống của mình không? Khi tôi thử và lặp lại $ expPS1, tôi nhận được "bash:: lệnh không tìm thấy ..." làm giá trị. Cũng lưu ý rằng đầu -1 có thể không hoạt động khi bạn có lời nhắc nhiều dòng. Ngoài ra, tôi đang in dấu nhắc của tôi bằng màu xanh đậm. Đây là lý do tôi đăng câu hỏi này: Tôi muốn giữ lại PS1 hoàn toàn mà không cần sao chép các phần tử của nó dưới bất kỳ hình dạng hoặc hình thức nào. Fyi, PS1 của tôi được đặt thành: ''\ [\ 033 [0; 34m \] \ u @ \ h $? \ w \ n $ \ [\ 033 [0m \] ''. Trong khi tôi chắc chắn thích sự khéo léo của giải pháp của bạn, nó rất chậm: có khoảng cách 1-2 giây trước khi tôi thấy bất kỳ kết quả nào cả. – Harry

+0

Đó thực sự là một danh sách giặt ủi của các vấn đề bạn có :-) (1) Có, tôi đã thử trên hệ thống của tôi, rằng bit cuối cùng là một bảng điểm thực tế. (2) Có, 'đầu -1' sẽ không hoạt động đối với lời nhắc nhiều dòng, bạn sẽ phải khéo léo hơn một chút và điều đó có thể sẽ cần phải biết trước số lượng dòng hoặc tiền xử lý' PS1' đếm Các phần '\ n'. (3) Tôi không chắc chắn vấn đề là gì với màu sắc mặc dù bạn có thể phải ép buộc cài đặt 'TERM' của bạn. (4) Tôi không thể xác minh cho tốc độ, điều đó phụ thuộc vào thời gian cần để bắt đầu trình bao. Nếu giải pháp thứ hai là không đủ, bạn có thể cần phải xem xét giải pháp đầu tiên. – paxdiablo

+0

Nhưng tôi nghi ngờ nó có thể là nỗ lực của _more_, mặc dù ít nhất nó cũng nên giải quyết những vấn đề đó. Bạn thậm chí có thể viết một kịch bản làm những việc tương tự với mã C để dịch một 'PS1' tùy ý. – paxdiablo