공백과 괄호가 포함된 경로 전달 문제

공백과 괄호가 포함된 경로 전달 문제

저는 Thunar File Explorer를 사용하고 오디오 재생을 위해 경로명과 파일명을 스크립트에 전달합니다. Audioplay는 SSH를 통해 Android에서 재생 명령을 실행하여 노래를 재생합니다.

오디오 재생 스크립트::cat audioplay

if [ $# -eq 1 ] ; then
echo "   Playing..." "$@"
sshpass -p $passwd  ssh [email protected] -p $port  play "$@"
else
 echo "  No Input audio file."
fi

내 Android에서 스크립트 재생::cat play

    #!/data/bin/bash
    # Avoid linker errors due to libOpenSLES.so:
    echo "File ::" "$@"
    LD_LIBRARY_PATH= exec /data/bin/blob/play-audio "$@"

문제는 SSH를 통한 재생 명령에 경로가 올바르게 전달되지 않는다는 것입니다. 공백이 여러 개 있는 경로는 단일 공백이 되며 괄호로 인해 구문 오류가 발생합니다.

예:

18. Warriors.flac존재하기 위해 /sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015

audioplay로 전송된 경로가 정확합니다::/sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015/18. Warriors.flac

그러나 재생 스크립트에서 수신한 경로가 잘못되었습니다. /sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015/18. Warriors.flac 여러 공백이 단일 공백이 됩니다. 왜?

그런 다음 기본 바이너리는 첫 번째 공백에 대한 경로만 가져옵니다 play-audio./sdcard/Music/Imagine

예 2::

File::을 대괄호로 사용해 보았습니다. 44. Go Tell Aunt Rhody -Resident Evil- (Short Version).flac 오디오 재생 스크립트에서 수신한 경로는 정확합니다::. /sdcard/Music/44. Go Tell Aunt Rhody -Resident Evil- (Short Version).flac 하지만 이 오류가 발생합니다::sh: syntax error: '(' unexpected

나는 통과를 시도 $@ $* "$@"했고 "$*". 그러나 그들 중 어느 것도 나에게 적합하지 않습니다.

답변1

다시 인용하자면:

if [ "$#" -eq 1 ] ; then
    echo "   Playing..." "$1"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
    echo "  No Input audio file."
fi

문제는 명령을 "$@"실행할 때 첫 번째 수준의 따옴표가 확장된다는 것입니다. sshpass따라서 로그인하고 원격 셸을 시작하고 실행하면 play따옴표가 없는 문자열이 표시되므로 스크립트가 공백을 차단합니다. 두 번째 따옴표로 묶어서 원격 명령에 따옴표로 전달되도록 합니다.

이는 i) 원격 시스템이 쉘 sh또는 bash이와 유사한 것을 실행 중이고 ii) 파일 이름에 작은따옴표가 포함되어 있지 않다고 가정하면 작동합니다. 정말 강력하게 만들려면 다음을 참조하세요.원격 사용자의 로그인 셸을 모르고 SSH를 통해 임의의 간단한 명령을 어떻게 실행할 수 있습니까?.

구문에서 임의의 문자열(또는 여러 인수를 전달할 수 있는 임의의 문자열 목록 play) 을 올바르게 참조하기 위해 여기에 언급된 함수를 sh사용할 수 있습니다 .shquote()

shquote() {
  LC_ALL=C awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
        printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}
if [ "$#" -ge 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play $(shquote "$@")"
else
    echo "  No Input audio file."
fi

Sgt. Pepper's lonely hearts club band.flac이것이 참조할 내용 이 'Sgt. Pepper'\''s lonely hearts club band.mp3'정확합니다 sh(그리고 원격 시스템을 다시 시작하는 evil';reboot;: '.flac대신'evil'\'';reboot;: '\''.flac'가지다play명령을 root? )).

관련 정보