이상한 오류가 발생했는데 이에 대해 아무것도 찾을 수 없습니다. 다음 명령을 사용하여 사용자 설명을 변경하고 싶습니다.
$ sudo usermod -c "New Comment" user
이는 서버에 로그인했을 때 작동하지만 20개 이상의 서버에서 자동화하고 싶습니다. 일반적으로 목록을 사용하여 서버를 통해 루프를 실행하고 명령을 실행할 수 있지만 이 경우 오류가 발생합니다.
$ for i in `cat servlist` ; do echo $i ; ssh $i sudo usermod -c "New Comment" user ; done
serv1
Usage: usermod [options] LOGIN
Options:
lists usermod options
serv2
Usage: usermod [options] LOGIN
Options:
lists usermod options
.
.
.
이 루프를 실행하면 명령을 잘못 사용한 것처럼 오류가 반환되지만 단일 서버에서는 제대로 실행됩니다.
SSH 매뉴얼 페이지를 보고 태그를 시도했지만 -t
아무 -t -t
것도 작동하지 않았습니다.
perl -p -i -e
비슷한 루프를 사용하여 파일을 편집했습니다 .
왜 루프할 수 없는지 아는 사람 있나요?
답변1
SSH는 셸에서 원격 명령을 실행합니다. 매개변수 목록 대신 문자열을 원격 셸에 전달합니다. 명령에 전달된 매개변수는 ssh
공백으로 구분됩니다. 매개변수 ssh
는 sudo
, usermod
및 -c
이므로 원격 쉘에서 명령을 볼 수 있습니다.New Comment
user
sudo usermod -c New Comment user
usermod
Comment
사용자 이름 및 거짓 추가 매개변수로 확인됩니다 user
.
주석이 문자열로 처리되도록 원격 셸에 따옴표를 전달해야 합니다. 가장 쉬운 방법은 전체 원격 명령을 작은따옴표로 묶는 것입니다. 이 명령에 작은따옴표를 사용해야 하는 경우 를 사용하세요 '\''
.
ssh "$i" 'sudo usermod -c "Jack O'\''Brian" user'
호출을 반복하고 오류를 무시하는 대신 ssh
pssh, mussh, Clustersh 등과 같은 여러 서버에서 명령을 실행하도록 설계된 도구를 사용하십시오. 보다많은 서버에서 SSH를 통해 명령 실행 자동화
답변2
for i in `cat servlist`;do echo $i;ssh $i 'sudo usermod -c "New Comment" user';done
또는
for i in `cat servlist`;do echo $i;ssh $i "sudo usermod -c \"New Comment\" user";done
답변3
다음과 같은 편리한 래퍼 스크립트를 사용할 수 있습니다.ssh.sh
2023/04/28에 수정되었습니다. 마침내 나는 @user202729가 언급한 문제를 과도하게 프로그래밍하지 않고 해결하는 완벽한 솔루션을 찾았습니다.
최종 SSH 래퍼는 다음과 같습니다.
#!/bin/bash
args=(); for v in "$@"; do args+=("$(printf %q "$v")"); done
ssh "${args[@]}"
복사하여 붙여넣고 실행하여 만들 수 있습니다.
cat <<'EOF' > ssh.sh
#!/bin/bash
args=(); for v in "$@"; do args+=("$(printf %q "$v")"); done
ssh "${args[@]}"
EOF
chmod +x ssh.sh
그러면 탈출에 대한 걱정 없이 SSH를 통해 안전하게 호출할 수 있습니다 ssh.sh
.
./ssh.sh host sudo usermod -c "New Comment" user
전체 테스트:
먼저 /tmp/show_args.sh 유틸리티를 생성하여 모든 인수를 표시합니다.
cat <<'EOF' > /tmp/show_args.sh
#!/bin/bash
for arg in "$@"; do echo "ARG$((++i))=${arg@Q}"; done
EOF
chmod +x /tmp/show_args.sh
완전한 테스트를 위해서는:
./ssh.sh 127.0.0.1 -n /tmp/show_args.sh "a a" "'b b'" '"c c"' '*' '()' $'line1\nline2' $'\001 a' 'zz '
출력은 다음과 같습니다
ARG1='a a'
ARG2=''\''b b'\'''
ARG3='"c c"'
ARG4='*'
ARG5='()'
ARG6=$'line1\nline2'
ARG7=$'\001 a'
ARG8='zz '
모든 매개변수가 입력과 동일한 것을 볼 수 있습니다. 노트
''\''b b'\'''
말 그대로
'b b'