SSH를 통해 복잡한 명령을 실행하는 Unix/Linux

SSH를 통해 복잡한 명령을 실행하는 Unix/Linux

SSH를 통해 서버에 연결한 다음 오늘의 파일을 찾은 다음 해당 파일 내에서 grep을 시도하고 있습니다. 하지만 오류가 발생합니다 find: missing argument to `-exec'.

내가 여기서 무엇을 놓치고 있는 걸까요?

ssh server.name find /dir1/subdir/filelist* -maxdepth 1 type f -mtime 0 -exec grep 'pattern' {} \;

답변1

코드에 문제가 있습니다.

  1. 로컬 셸은 /dir1/subdir/filelist*하나 이상의 일치하는 경로로 확장될 수 있습니다. 이러한 경로는 원격 측에 존재할 수도 있고 존재하지 않을 수도 있습니다.

  2. ssh얻은 여러 매개변수를 기반으로 셸 코드를 로컬에서 빌드합니다(원격 측에서 실행). 주장은 다음과 같습니다:

    • find
    • /dir1/subdir/filelist*(로컬 일치 항목이 없는 경우)
    • -maxdepth
    • 1
    • -typetype( 오타를 하신 것 같아요 )
    • 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

관련 정보