Bash

傳遞包含空格和括號的路徑的問題

  • September 26, 2017

我使用 Thunar 文件資源管理器並將路徑名和文件名傳遞給腳本音頻播放。audioplay 通過播放歌曲的 ssh 在我的 android 上執行播放命令。

音頻播放腳本::cat audioplay

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

在我的安卓上播放腳本 ::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

發送到音頻播放的路徑是正確的 ::/sdcard/Music/Imagine Dragons - Smoke Mirrors -Deluxe Edition-2015/18. Warriors.flac

但是play腳本接收到的路徑錯誤 ::/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

我嘗試通過$@ $* "$@"and "$*"。但他們都沒有為我工作。

再次引用:

if [ "$#" -eq 1 ] ; then
   echo "   Playing..." "$1"
   sshpass -p "$passwd" ssh root@192.168.43.10 -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 root@192.168.43.10 -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?))。

引用自:https://unix.stackexchange.com/questions/394568