传递包含空格和括号的路径时出现问题

传递包含空格和括号的路径时出现问题

我使用 Thunar 文件资源管理器并将路径名和文件名传递给脚本音频播放。 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::

我尝试使用带有方括号的文件 ::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命令时,第一层引号会展开。因此,当您登录、启动远程 shell 并执行时play,您会得到一个不带引号的字符串,因此您的脚本会因空格而阻塞。通过将其括在第二层引号中,可以确保将其带引号传递给远程命令。

假设 i) 远程计算机正在运行shbash类似的 shell 以及 ii) 您的文件名不包含单引号,这应该可以工作。为了使其真正强大,请参阅如何在不知道远程用户的登录 shell 的情况下通过 ssh 执行任意简单命令?

为了在语法中正确引用任意字符串(甚至是任意字符串列表,以便您可以向 传递多个参数playsh,我们可以使用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?))。

相关内容