SSH를 통해 서버에 연결한 다음 오늘의 파일을 찾은 다음 해당 파일 내에서 grep을 시도하고 있습니다. 하지만 오류가 발생합니다 find: missing argument to `-exec'
.
내가 여기서 무엇을 놓치고 있는 걸까요?
ssh server.name find /dir1/subdir/filelist* -maxdepth 1 type f -mtime 0 -exec grep 'pattern' {} \;
답변1
코드에 문제가 있습니다.
로컬 셸은
/dir1/subdir/filelist*
하나 이상의 일치하는 경로로 확장될 수 있습니다. 이러한 경로는 원격 측에 존재할 수도 있고 존재하지 않을 수도 있습니다.ssh
얻은 여러 매개변수를 기반으로 셸 코드를 로컬에서 빌드합니다(원격 측에서 실행). 주장은 다음과 같습니다:find
/dir1/subdir/filelist*
(로컬 일치 항목이 없는 경우)-maxdepth
1
-type
type
( 오타를 하신 것 같아요 )f
-mtime
0
-exec
grep
pattern
(로컬 쉘에 따옴표가 부족하기 때문에){}
;
(로컬 쉘은 백슬래시를 사용하기 때문에)
빌드할 쉘 명령은 다음과 같습니다.
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep pattern {} ;
find
(원격) 쉘은 이를;
명령 종결자로 해석하여;
도달할 수 없기 때문에 유효한 명령이 아닙니다find
. 또한pattern
원격 쉘의 컨텍스트에서는 가 인용되지 않습니다.
나는 이것이 정확히 원격 측의 셸에서 실행하려는 명령이라고 생각합니다.
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;
바라보다SSH를 통해 복잡한 명령줄을 실행하는 방법그리고 내 대답. 여기서는 모든 내용을 반복하지 않겠습니다. 가장 중요한 것:
원격 셸이 얻는 것을 제어하려면
$command_line_built_by_ssh
이전에 발생한 구문 분석 및 해석을 이해하고 예측하고 조율해야 합니다. 로컬 명령을 내려야 하므로뒤쪽에ssh
로컬 셸을 실행하고 이를 소화하면 원격 측에서 실행하려는 내용이 정확하게 됩니다 .$command_line…
ssh
기본적인 해결책은 정확한(원격) 명령을 단일 인수로 로컬에 전달하는 것입니다. 귀하의 경우 로컬 명령은 다음과 같습니다.
ssh server.name 'find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep '\''pattern'\'' {} \;'
관련 질문에 대한 답변에서 몇 가지 더 많은 아이디어를 논의합니다.
답변2
이 ssh 명령으로 여러 명령을 실행하는 것이 아니라 더 복잡한 find 명령을 실행하는 것입니다.
여기에는 두 가지 주요 문제가 있습니다.
- 명령을 작성하는 방법에 따라 glob 패턴이 클라이언트에서 평가됩니다.
;
명령에 도달하지 못했기 때문에 오류 메시지가 발생합니다find
. 기본적으로ssh
매개변수를 연결하여sh -c
서버에 전달합니다. 당신은 그런 것이 필요합니다\\\;
.
서버에 stdin이 필요하지 않은 한 가장 간단한 해결책은 stdin의 명령을 셸로 보내는 것입니다. 이렇게 하면 따옴표가 필요하지 않습니다.
ssh server.name /bin/sh <<'EOF'
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;
EOF