쉘 스크립트에서 exec를 사용하여 SSH를 통해 찾기

쉘 스크립트에서 exec를 사용하여 SSH를 통해 찾기

그래서 쉘 스크립트에서 다음 명령을 실행해 보았습니다.

ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \; exit"

실행하면 다음 오류가 생성됩니다.

find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

Google에서 찾은 내용을 바탕으로 여러 가지 변형을 시도했지만 문제가 해결되지 않는 것 같습니다. 누구든지 이것에 무슨 문제가 있는지 말해 줄 수 있습니까?

참고로, 대상 호스트에 수동으로 로그인하고 그곳에서 동일한 find 명령을 실행하면 정상적으로 작동합니다. 그래서 나는 ssh 명령의 큰따옴표 안에 명령을 삽입하는 것과 관련이 있다고 생각합니다.

답변1

문법적인 문제가 좀 있는데,그들 중 하나치명적이고다른이것은 어느 시점에서 당신을 물릴 수 있습니다.

그런데 +대체 명령 으로 ;-exec명령을 끝낼 수 있습니다. 이렇게 하면 gzip일괄적으로 실행되며 약간 더 빠릅니다.

LOGS_DIR값이 이면 /somewhere/with/logs원격 호스트에서 다음 명령을 실행합니다.

cd /somewhere/with/logs; echo cd /somewhere/with/logs; find . -name *.log -mmin +1440 -exec gzip {} \; exit

또는 해당 세미콜론 연산자를 개행 문자로 바꿉니다.

cd /somewhere/with/logs
echo cd /somewhere/with/logs
find . -name *.log -mmin +1440 -exec gzip {} \; exit

명령 다음에 잘못된 내용이 표시되면 find이를 어떻게 해야 할지 알 수 없습니다. 이는 사용자가 해당 내용을 통과할 경로로 의도했다고 (잘못) 추측할 수 있습니다. 명령 구분 기호가 필요합니다. 그 뒤에 또 다른 명령 구분 기호를 넣으세요(앞에 공백이 있든 없든).exit-exec … ;;\;

두 번째 문제는 와일드카드 패턴이 *.log디렉토리 내에서 확장된다는 것입니다 /somewhere/with/logs. 일치하는 파일(즉, 형식의 파일 /somewhere/with/logs/something.log)이 존재하는 경우 패턴은 일치하는 파일로 대체됩니다. 이는 *.log원격 쉘에 find가 볼 수 있는 변경되지 않은 일치 항목이 없는 경우에만 발생합니다. 이런 일이 발생하지 않도록 패턴 주위에 따옴표를 추가하세요.

세 번째 문제는 의 가치이다 LOGS_DIR. 로컬에서 문자열로 확장되고 원격 측에서 쉘 스크립트로 실행됩니다. 따라서 쉘 특수 문자(공백 등)가 있으면 $모든 원격 명령을 실행할 수 있습니다 . 대부분의 문자를 인용하는 빠르고 더러운 방법은 변수 확장 주위에 작은따옴표를 두는 것입니다. 이는 값에 작은따옴표가 포함된 경우에만 중단됩니다. 로컬 스크립트가 bash를 실행 중인 경우 작은따옴표를 4개의 문자 시퀀스로 바꾸어 '\''값을 보호할 수 있습니다 LOGS_DIR.

ssh -q "$CUR_HOST" "cd '${LOGS_DIR//\'/\'\\\'\'}'; find . -name '*.log' -mmin +1440 -exec gzip {} +; exit"

답변2

";"을 추가하는 것을 잊었습니다:

ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \;; exit"

누락되었으므로 ;find 는 이를 exit경로로 해석합니다.

관련 정보