원격 시스템의 /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는 공백과 결합되므로 , ,는 foo
과 bar
동일하게 보입니다 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 ;