명령 대체가 후행 줄 바꿈을 제거하는 것을 방지하는 우아한 방법

명령 대체가 후행 줄 바꿈을 제거하는 것을 방지하는 우아한 방법

zsh를 사용자 정의 하고 환경 변수의 상태에 따라 문자열일 PROMPT수도 있고 아닐 수도 있는 함수를 호출합니다 .echo

function my_info {
    [[ -n "$ENV_VAR"]] && echo "Some useful information\n"
}

local my_info='$(my_info)'

PROMPT="${my_info}My awesome prompt $>"

정보가 후행 줄 바꿈으로 끝나서 정보가 설정된 경우 자체 줄에 표시되기를 원합니다.

Some useful information
My awesome prompt $>

그러나 설정되지 않은 경우 프롬프트에서 무조건 개행으로 인해 빈 줄이 발생하는 것을 방지하기 위해 프롬프트를 한 줄에 표시하고 싶습니다.

PROMPT="${my_info}  # <= Don't want that :)
My awesome prompt $>"

현재는 $(command substitution)개행 문자 뒤에 인쇄되지 않는 문자를 추가하여 개행 문자를 제거하는 문제를 해결하고 있으므로 개행 문자가 더 이상 뒤에 오지 않습니다.

[[ -n "$ENV_VAR"]] && echo "Some useful information\n\r"

이것은 분명히 해킹입니다. 줄바꿈으로 끝나는 문자열을 반환하는 깔끔한 방법이 있나요?

편집하다:알겠어요후행 줄 바꿈이 손실되는 원인그리고왜 이런 일이 발생합니까?, 하지만 이 질문에서는 특히 이러한 동작을 방지하는 방법을 알고 싶습니다.이 솔루션"조건부" 개행 문자를 찾고 있기 때문에 제 경우에는 작동합니다.)

편집하다:수정하겠습니다.참조 솔루션실제로는 꽤 좋은 해결책일 수 있지만(비교에서 문자열 앞에 접두사를 붙이는 것은 일반적이고 다소 유사한 패턴이기 때문에) 작동하도록 할 수는 없습니다.

echo "Some useful information\n"x
  [...]
PROMPT="${my_info%x}My awesome prompt $>"

x나를 위해 후행을 제거 하지 않습니다 .

편집하다:급속한 확장이라는 이상한 문제를 해결하기 위해 제안된 해결 방법을 적용한 결과 다음과 같은 결과가 나왔습니다.

function my_info {
    [[ -n "$ENV_VAR"]] && echo "Some useful information\n"x
}

local my_info='${$(my_info)%x}'

PROMPT="$my_info My awesome prompt $>"

이것이 원래 솔루션보다 더 나은 솔루션인지 알 수 있습니다. 좀 더 명확하다고 생각하지만 가독성이 떨어지는 느낌도 듭니다.

답변1

마지막 개행 문자는 명령 대체에서 제거됩니다. zsh조차도 이를 방지할 수 있는 옵션을 제공하지 않습니다. 따라서 최종 개행 문자를 유지하려면 최종 개행 문자가 되지 않도록 배열해야 합니다.

가장 간단한 방법은 정확하게 얻으려는 데이터 뒤에 추가 문자(개행 제외)를 인쇄하고 명령 대체 결과에서 마지막 추가 문자를 제거하는 것입니다. 해당 추가 문자 뒤에 줄바꿈을 추가하도록 선택할 수 있지만 어쨌든 제거됩니다.

zsh에서는 명령 대체와 문자열 조작을 결합하여 불필요한 문자를 제거할 수 있습니다.

my_info='${$(my_info; echo .)%.}'
PROMPT="${my_info}My awesome prompt $>"

귀하의 시나리오에서 이는 my_info명령의 출력이 아니라 출력을 가져오는 데 사용되는 셸 조각이며 프롬프트가 확장될 때 평가됩니다. 변수의 값에서 최종 값을 제거 PROMPT=${my_info%x}…하려고 시도하기 때문에 작동하지 않지만 로 끝납니다 .xmy_info)

다른 셸에서는 이 작업이 두 단계로 수행됩니다.

output=$(my_info; echo .)
output=${output%.}

my_infoBash에서는 에서 직접 호출 할 수 없습니다 PS1. 에서 호출해야 합니다 PROMPT_COMMAND.

PROMPT_COMMAND='my_info=$(my_info; echo .)'
PS1='${my_info%.}…'

답변2

확장 시 개행 문자가 되도록 함수가 이스케이프의 이스케이프 코드를 출력하도록 할 수 있습니다.

$ function my_info {
>    [[ -n "$ENV_VAR"]] && echo 'Some useful information\\n'
>}
$ echo $(my_info)
Some useful information

$

관련 정보