함수에서 SSH 명령을 실행하고 출력을 변수에 저장하려면 어떻게 해야 합니까?

함수에서 SSH 명령을 실행하고 출력을 변수에 저장하려면 어떻게 해야 합니까?

내 함수(.bashrc에 포함됨) 중 하나에서 다음 명령을 실행하여 다른 서버에 저장된 파일의 경로를 찾고 변수에 저장하려고 합니다.

FILE_PATH=$(ssh -T user@host 'find <directory> -name *<filename>*')

그러나 이는 출력을 반환하지 않습니다. 스크랩한 위치에 파일이 있어야 하는지 확인도 했고, 명령줄에서 명령어를 복사해서 출력값을 변수에 저장하는 것도 가능한데, 함수 실행시에는 동작하지 않네요.

무슨 일이 일어나고 있고 명령이 작동하지 않는 이유를 아는 사람이 있습니까?

편집하다:

내가 보고 있는 것을 다음과 같이 표현합니다.

function get_path {
    FILE=$1
    FILE_PATH=$(ssh -T user@hostB 'find /home/daverbuj -name *${FILE}*')
    echo "Here is the file: ${FILE_PATH}"
}
[daverbuj@hostA]$ FILE_A=$(ssh -T user@hostB 'find /home/daverbuj -name foo.bar')
[daverbuj@hostA]$ echo $FILE_A
/home/daverbuj/foo.bar

[daverbuj@hostA]$ get_path foo.bar
Here is the file:

명령줄에서 실행하면 예상한 결과가 표시되지만 함수를 실행하면 결과가 표시되지 않습니다.

답변1

get_path() {
  local name=$1
  readarray -td '' reply < <(
    LC_FILE_NAME=$name ssh -o SendEnv=LC_FILE_NAME -n -T user@hostB '
      LC_ALL=C find /home/daverbuj -name "*$LC_FILE_NAME*" -print0')
  (( ${#reply[@]} )) &&
    echo "File path${reply[2]+s} with that name:" &&
    printf ' - %s\n' "${reply[@]}"
}
  • function f {...}ksh 스타일 함수 정의( ) 를 사용할 필요가 없으며 bash표준도 지원됩니다.f() compound-command
  • 일치하는 파일이 여러 개 있을 수 있습니다. 안정적으로 구분하려면 NUL을 구분 기호( )로 사용해야 합니다 -print0. bash변수는 NUL을 보유할 수 없지만 버전 4.4부터 readarray내장 함수는 NUL로 구분된 입력 스트림을 -d ''.
  • *find전역 연산자이므로 이름 패턴 일치 연산자 에 축어적으로 전달하려면 로컬 및 원격 쉘 모두에 대해 인용되어야 합니다 -name.
  • 로컬 셸이 변수를 원격 셸에 전달된 코드로 확장하는 것을 원하지 않습니다. 이는 일종의 임의 명령 주입 취약점을 구성하기 때문입니다. 대신 여기에서 환경 변수를 통해 원격 셸에 $name값을 전달합니다 LC_FILE_NAME( sshd구성된 것으로 가정). 원격 호스트 universal에서 AcceptEnv LC_*). 코드에서 원격 쉘이 $FILE변수를 확장하지만(인용하는 것을 잊었지만 *) 로컬 쉘에서 원격 쉘로 변수를 전달하지 않습니다.
  • $REPLYfor scalar 및 $replyfor array는 변수 이름에 대한 일반적인 규칙이며 결과를 호출자에게 반환합니다.
  • 임의의 데이터 에는 이를 사용할 수 없습니다 echo(백슬래시가 포함되지 않거나 로 시작하지 않는다고 보장할 수 없음 -).
  • -name '*foo*'foofnmatch()파일 이름을 해당 문자 집합으로 디코딩할 수 없으면 s를 사용하여 오류가 발생하므로 멀티바이트 문자 집합(예: UTF-8)을 사용하여 이름의 모든 파일을 일치시키는 것이 불가능할 수 있습니다 . 따라서 단일 바이트 로케일로 고정되었습니다.find-nameLC_ALL=C
  • 여기서는 최소한 하나의 파일이 발견되어 올바르게 인쇄되지 않으면 실패한 종료 상태를 반환합니다.
  • 표준 입력의 입력을 소비하지 않도록 -n옵션을 사용합니다 . 무인 처리와 관련된 조정을 ssh하나 더 추가할 수도 있습니다 .-o BatchMode=yes

여기에서 더 읽어보세요:

답변2

stderr경로를 재설정 하여 stdout사용할 수 있습니다.

OUT=$(ssh -tt -vv [email protected] "remote command" 2>&1 )

함수에서 이와 같은 내용을 편집하면 제대로 작동할 것입니다!

관련 정보