제안에 따라 편집된 명령

제안에 따라 편집된 명령

원격 시스템의 /etc/profile. 이제 이 문자열을 70개 이상의 서버에 추가해야 하므로 를 사용하여 ssh모든 서버에 이 PS1 문자열을 추가하겠습니다. 하지만 PS1을 보내려고 하면 작동이 중단되고 명령을 종료해야 합니다.

이것은 명령이다

ssh -v admin@remserv  "sed  '/002/a \ PS1=" \[\e[31m\]\n------------------------------------------------------------------------------------------------------------------------------ \n\n[\u@\h \W]\\$ - \# \[\e[0m\] " /etc/profile' "

여기에 이미지 설명을 입력하세요

내가 여기서 무엇을 놓치고 있습니까?

제안에 따라 편집된 명령

> ssh -vt admin@remserv printf "%s\n" "sudo sed -i.bak '/002/a \
> PS1="
> '\[\e[31m\']'\'n------------------------------------------------------------------------------------------------------------------------------ '\'n'\'n'[\u@\h \W']'\\'$ - '\'# '\[\e[0m\']  " /etc/profile' "

답변1

ssh ... "sed  '/002/a \ PS1=" \[\e[31m\]\n--...- \# \[\e[0m\] " /etc/profile' "
              ^             ^                                 ^             ^

인용된 문자열 안에 인용되지 않은 두 개의 큰따옴표가 있으며, 이는 쉘(ssh 연결의 로컬 측)에 의해 제거됩니다. 또한 내부 작은따옴표는 sed명령과 파일 이름 모두에 걸쳐 있는 것처럼 보이므로 원격 쉘이 인용을 처리한 후 sed/002/a \ ... /etc/profile. 이는 실제로 이미지의 SSH 출력에 표시됩니다.

(글쎄, 적어도 그것이 마음에 떠오르는 것입니다. 적어도 커피가 충분하지 않으면 큰 따옴표 문제가 내 두뇌에 잘 작동하지 않습니다.)

다음과 같은 것을 실행하여 디버깅할 수 있어야 합니다.

ssh somewhere printf '"%s\n"'  "sed '/002/... /etc/profile' "

printf한 줄에 하나씩 가져온 인수를 인쇄하므로 문자열이 실제로 분할된 위치를 확인하기가 더 쉽습니다(echo는 공백과 결합되므로 , ,는 foobar동일하게 보입니다 foo bar). 백슬래시를 리모컨에 그대로 유지하려면 형식 문자열을 큰따옴표로 묶습니다.

답변2

좋습니다. '\' 문자를 사용하여 이 문제를 해결하세요.

올바른 명령

for i in `cat serverslist`; do  ssh -t admin@$i  "sudo sed -i.bak '/002/a \ PS1="\" '\\'['\\'e[31m'\\']'\\n'------------------------------------------------------------------------------------------------------------------------------  '\\'n'\\'n['\\'u@'\\'h '\(''\\'W'\)']'\\''\\'$ - '\\'# '\\'['\\'e[0m'\\']   \"" ' /etc/profile " ;done ;

관련 정보