2012-04-08 7 views
8

가능한 중복 :
Echo expanded PS1bash : PS1, PS2, ... 평가하는 방법?

은 bash는 스크립트 내에서 PS1, PS2 등을 '평가'하는 방법은 없나요?

대체 수단을 사용하여 현재 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> 

그러나, 이것은 실제로 현재 쉘 하나보다는 당신에게 정기적 인 메시지를 줄 것이다 프롬프트 다중 회선에 문제가 : 내 시스템에서

, 이것은 내가 무엇을 얻을 수 있습니다.


당신이 제대로은 그 자체 bash에 약간의 추가 포함 할 수 하고 싶은 경우

. 다음은 내부 명령어 인 evalps1을 추가하는 단계입니다.

먼저 bash "진짜", 그래서 FSF는 간단하게 한 줄을 변경 :-) 보증 목적에 대한 모든 지식을 거부 할 수 있음 (필자는 -pax 비트를 추가)를와 혼동하지 않도록 support/mkversion.sh을 변경 :

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

둘째,`builtins/Makefile.in '을 변경하여 새 소스 파일을 추가하십시오. 이것은 많은 단계를 수반한다.

(a) DEFSRC 끝에 $(srcdir)/evalps1.def을 추가하십시오.

(b) OFILES 끝에 evalps1.o을 추가하십시오.

(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 명령을 실행할 때

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

셋째, builtins/evalps1.def 파일 자체를 추가,이 실행됩니다 코드입니다 그것의 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에 코드 변경을하면 추가 할 n 내부 명령어는 과잉으로 간주 될 수 있지만, 정확히 PS1의 정확한 평가를 원한다면, 그것은 확실히 선택 사항입니다.

+0

정말 시스템에서 해봤습니까? 내가 $ expPS1을 시도하고 echo했을 때, "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) 속도를 보증 할 수는 없습니다. 쉘을 시작하는 데 걸리는 시간에 따라 다릅니다. 두 번째 솔루션이 부적절한 경우 첫 번째 솔루션을 살펴볼 필요가 있습니다. – paxdiablo

+0

하지만 적어도 그것이 그 문제를 해결해야한다고는해도 _more_ 노력일지도 모른다. 임의의'PS1'을 번역하기 위해 C 코드와 비슷한 일을하는 스크립트를 작성할 수도 있습니다. – paxdiablo

관련 문제