![다른 사용자로 원격 서버에서 명령을 실행하는 방법](https://linux55.com/image/62369/%EB%8B%A4%EB%A5%B8%20%EC%82%AC%EC%9A%A9%EC%9E%90%EB%A1%9C%20%EC%9B%90%EA%B2%A9%20%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
SSH를 사용하여 서버 A에서 서버 B로 연결하고 다른 사용자를 사용하여 명령을 실행하려고 합니다. 하지만 로그 파일에서 패턴을 검색하려고 하면 "로그 파일을 열 수 없습니다"라는 메시지가 나타납니다. 아래는 샘플 코드입니다.
ssh -t user@hostname <<EOF
sudo su - someotheruser
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ $a -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
EOF
스크립트를 실행하면 다음과 같이 표시됩니다.unable to open "tail........."
서버 B에 로그인 상태를 유지하면서 여러 명령을 실행할 수 없습니다.
답변1
각 명령이 실행되는 시기, 실행되는 위치, 수신되는 입력을 신중하게 고려하십시오.
- 여기에서 문서를 확장하여 시작하세요. 이는
tail
/ 파이프라인이 변수 대체와 마찬가지로awk
localhost에서 실행된다는 것을 의미합니다.$a
- 그런 다음
ssh
명령을 실행하십시오. 여기에서 확장된 문서를 수신합니다. 이는 원격 셸에서 실행되는 명령입니다. - 원격 셸은 인수 없이 실행되므로 표준 입력에서 실행할 명령을 읽습니다. 이러한 명령에는 가 포함되지만
sudo
(셸에 따라) 다음 행 중 일부가 포함될 수도 있습니다. - 원격 쉘 실행 . 먼저 해당 사용자의 명령을 읽고 실행한 다음 표준 입력에서 명령을 읽는
sudo su - someotheruser
쉘을 실행합니다 . 표준 입력에는 첫 번째 원격 셸에서 읽지 않은 콘텐츠가 포함되어 있어 다소 예측할 수 없습니다(셸과 입력 파이프에서 읽는 양에 따라 다름).someotheruser
.profile
- 실행 중인 셸은
someotheruser
읽은 명령(있는 경우)을 실행합니다. - 실행 중인 쉘은 명령을 읽었으면 명령을
someuser
실행합니다 .if
여기서 문서 확장을 방지하려면 heredoc 태그 주위에 따옴표를 사용하십시오. 표준 입력의 부적절한 혼합을 방지하려면 sh -c …
두 번째 원격 셸에서 수신한 입력을 사용하거나 지정하십시오.
ssh -t user@hostname <<'SSH_EOF'
sudo su - someotheruser <<'SU_EOF'
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SU_EOF
SSH_EOF
소스 코드가 정말 필요 someotheruser
합니까 .profile
? 그렇지 않다면 을 사용 sudo -u someotheruser
하십시오. 그렇다면 sudo -i -u someotheruser
sudoers 규칙을 적절하게 조정하십시오.
로그 파일을 읽는 것은 높은 권한이 필요한 유일한 작업 tail
이므로 someotheruser
.
ssh -t user@hostname <<'SSH_EOF'
a=`sudo -u someotheruser tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SSH_EOF
권한 상승 방법을 혼합하지 않으면 인생이 훨씬 쉬워질 것입니다. sudo
스위치 someuser
를 사용하는 대신 someotheruser
SSH를 사용하여 localhost에 연결하십시오. 두 개의 SSH 명령을 연결하는 것은 쉽습니다. 키 설정 - 특정 명령만 실행하도록 허용하는 키를 설정할 수도 있습니다(예: tail -10 /somepath/application.log
계정 .ssh/config
을 통해 SSH에 대한 별칭 정의) someuser
.
Host hostname-someotheruser
HostName hostname
UserName someotheruser
ProxyCommand ssh someuser@hostname
그런 다음 실행
a=$(ssh hostname-someotheruser tail -10 /somepath/application.log |
awk '/Agent Exited/ { print $3 }')
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
답변2
If 문은 명령이 아니며 쉘에서 해석되어야 합니다. 이것을 시도해 볼 수 있습니다. 로컬 스크립트 만들기
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
[ $a -eq 0 ] && echo "Success" || echo "Faiilure"
bash 쉘을 호출하여 이러한 명령을 실행하십시오.
ssh -t user@hostname 'echo "pass" | sudo -Sv && bash -s' < script.sh
답변3
귀하의 설명으로 볼 때 두 가지 문제가 있다고 생각됩니다. 우선, 그럴 필요는 없습니다 <
. 매뉴얼 페이지에 따르면 ssh
호스트 이름 뒤에 오는 문자열은 원격으로 실행되는 명령으로 즉시 인식됩니다. 여러 명령을 실행하려면 모든 명령을 작은따옴표로 묶은 문자열에 넣을 수 있습니다. 이 문자열은 원격으로 전송되어 스크립트처럼 실행됩니다.
ssh -t user@hostname 'tail -10 /somepath/application.log | awk \'/Agent Exited/ { print $3 }\'; if [ $a -eq 0 ]; then echo "Success"; else echo "Failure"; fi'