무슨 일이야?

무슨 일이야?

echo을 사용하여 Puppet 규칙 내에 줄을 추가 하려고 하는데 .bashrc인용이 제대로 되지 않는 것 같습니다.

'/usr/bin/echo -E PS1=\"[\t--------------------------------------------------------\n-\u@\h:\W]\$\" >> /home/unu/.bashrc'

이것은 나에게 다음과 같은 결과를 제공합니다.

PS1="[t--------------------------------------------------------n-u@h:W]$"

또 다른 시도:

'/usr/bin/echo -E PS1="[\t--------------------------------------------------------\n-\u@\h:\W]\$" >> /home/unu/.bashrc'

이것은 나에게 다음을 제공합니다:

PS1=[\t--------------------------------------------------------\n-\u@\h:\W]$

또 다른:

'/usr/bin/echo -e PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$" >> /home/unu/.bashrc'

이것은 나에게 이것을 제공합니다 :

PS1=[   --------------------------------------------------------
-\u@\h:\W]$

\어떤 식 으로든 "설명 하지 않고서는 이 작업을 수행할 수 있는 방법을 찾을 수 없는 것 같습니다 . 어떻게 해야 합니까?

더 많은 따옴표를 사용하려고 생각했지만 이로 인해 Puppet에 구문 오류가 발생했습니다.

"/usr/bin/echo -e 'PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$"' >> /home/unu/.bashrc"

다음 결과를 얻었습니다.

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Syntax error at '' (file: /etc/puppetlabs/code/environments/production/modules/profile/manifests/ps1.pp, line: 3, column: 38) on node centoslave1

전체 코드는 다음과 같습니다.

class profile::ps1 {
        exec { 'myps1':
        command => "/usr/bin/echo -e 'PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$"' >> /home/unu/.bashrc"
        }
}

답변1

무슨 일이야?

명령 => "/usr/bin/echo -e 'PS1="[\\t------------------ -- ---------------- --------------------------\\N-\\ u@\\ h:\\W]\\$"' >> /Home/unu/.bashrc"

무엇이 잘못되었는지 이해하는 것이 이를 바로잡는 단서입니다. =>요소의 오른쪽( 뒤 )은 문자열이어야 합니다. 문자열은 Puppet에서 다양한 형태로 제공됩니다. 큰따옴표로 묶인 문자열은 큰따옴표로 시작하고 두 번째 세트로 끝납니다. 그래서 당신의 문자열은

"/usr/bin/echo -e 'PS1="
그런 다음 매니페스트에 구문상 올바르지 않은 횡설수설을 추가할 수 있습니다.

[\티----------------------------------------------- -- ------------- ---------\n-\u@\h:\W]\$
그리고 또 다른 문자열:

"'>>/home/unu/.bashrc"

올바르게 수행하십시오.

아래에서 위로 올바른 설정을 구축하세요. 명령이 파일에 출력할 내용부터 시작하십시오. 출력은 PS1쉘 변수를 다음과 같이 설정하는 쉘 명령입니다.

[\티----------------------------------------------- -- ------------- ---------\n-\u@\h:\W]\$
이러한 명령은 작은 따옴표를 사용하여 쉘이 이스케이프 시퀀스를 이스케이프하는 것을 방지하는 것입니다 (여기에서는 \및 문자를 $이스케이프할 필요가 없으므로 큰 따옴표가 선호됩니다 ).

PS1='[\t------------------------------- -- ------------ ------------\n-\u@\h:\W]\$'
echoecho셸 호출을 통해 이와 같은 명령을 출력할 수 있지만(이에 대해서는 나중에 다시 설명) 이스케이프를 더 많이 사용하여 작은따옴표가 명령에 도달하는지 확인해야 합니다 .

echo PS1=\''[\t---------------- -------------- ---------------\n-\u@\h:\W]\$'\'

그러나 이는 echo플랫폼과 셸 전반에 걸쳐 일관된 동작이 없기 때문에 문제가 되며 (아이러니하게도)가능한이스케이프 시퀀스의 변환은 실제로아니요당신은 무엇을 원합니까? 실제로 질문의 태그에도 불구하고 명령이 실행되는 셸은 운영 체제(아직 지정하지 않음)에 따라 반드시 Bourne Again 셸일 필요는 없습니다. 예를 들어 Debian Almquist 셸일 수 있습니다. 더 나은 결과를 얻으려면 다음을 사용하십시오 printf.

printf "PS1='%s'\n" '[\t---------------------- - --------\n-\u@\h:\W]\$' >> /home/unu/.bashrc

지금까지는 실행을 위해 쉘에 제공된 명령줄이라고 가정했습니다. 전달된 인수는 쉘 규칙에 따라 올바른 내용이 되도록 echo이스케이프 처리되고 인용됩니다 . printf따라서 제공자에 대한 문제의 댓글에 주의하시기 바랍니다.

이제 코딩을 해야 한다저것꼭두각시 문자열에서. '합계 문자 만 이스케이프 처리하면 되므로 작은 따옴표로 묶은 문자열을 선택하는 것이 더 좋습니다 \(이것은 다음과 같습니다).껍데기작은따옴표 문자열에 대한 규칙(참고):

명령 => 'printf "PS1=\'%s\'\\n" \'[\\t------------- ------------------------------------- -\\n-\\ u@\\h:\\W]\\$\ ' >> /home/unu/.bashrc'

추가 읽기

답변2

캐릭터를 소비할 수 있는 요소에는 (적어도) 두 가지 수준이 있습니다.

  1. 껍데기
  2. echo그 자체

실행하는 경우:

echo "hello, \"world\""

당신은 출력을 얻습니다

hello, "world"

왜냐하면껍데기에코 대신 백슬래시에서 큰따옴표를 사용합니다. 쉘은 이를 쉘 구문으로 처리합니다. 즉, hello, "world"단일 인수로 echo에 전달됩니다. 그런 다음 에코와 개행 문자를 인쇄합니다.

echo -e특히 백슬래시 시퀀스도 해석됩니다(구현에 따라 다름). 이를 해결하는 간단한 방법은 를 printf '%s\n' WHATEVER사용하는 것입니다 echo WHATEVER.

대부분의 경우 작은따옴표를 사용하여 쉘로부터 무언가를 보호할 수 있습니다(작은따옴표 자체가 포함되지 않는 한). 따라서 다음을 수행할 수 있습니다.

printf '%s\n' 'PS1="[\t--------------------------------------------------------\n-\u@\h:\W]\$"'

이것은 만든다:

PS1="[\t--------------------------------------------------------\n-\u@\h:\W]\$"

여러 단계의 쉘 이스케이프에서 살아남아야 한다면 printf '%q\n' WHATEVER쉘에서 살아남는 형식으로 인쇄하는 것이 유용할 수 있습니다(그러나 이것은 Bash 고유 기능일 수 있으므로 아직 확인하지 않았습니다).

참고: 작은따옴표로 묶인 문자열 내에서 작은따옴표를 보호해야 하는 경우 다음을 수행해야 합니다 '\''.

$ printf '%s\n' 'i'\''ll'
i'll

자세히 보면 실제로는 'i'++입니다.\''ll'

추신: PS1또 다른 확장을 거쳤습니다(Bash 문서 참조) \u. 그러나 변수도 확장됩니다. 따라서 끝에 뭔가가 있으면 $이를 이스케이프해야 합니다(큰따옴표 안에 있는 경우 백슬래시를 사용하세요.)PS1="foo\\\$PATH % "

답변3

사용 printf:

printf '%s\n' 'PS1="[\t--------------------------------------------------------\n-\u@\h:\W]\$"' >> /home/unu/.bashrc

답변4

다음을 간단히 사용할 수 있습니다 cat.

cat /var/tmp/ps1-file >> /home/unu/.bashrc

선호하는 편집기를 사용하여 수동으로 생성할 수 있으므로 ps1-file//에서 문제가 발생하는 것을 방지할 수 있습니다. 이 파일이 노드에 도달하려면 다음을 추가해야 합니다.bashechoprintf문서부분.

file { "/var/tmp/ps1-file"
    source => 'puppet:///modules/bashrc/ps1'
}

이는 원본 파일을 modulepath.할 수 있다로 지정 content =>하지만 이로 인해 자체 인용/이스케이프 문제가 발생합니다.

관련 정보