我需要使用 scm 將檔案從遠端主機複製到本機目錄,其中檔案有空格,否則我透過 ssh 到該主機並 scp 將檔案傳回來修復問題。但我想知道如何複製該文件,例如本地主機可能沒有安裝 sshd。
我試過這個:
scp [email protected]:~/download/file\ that\ have\ spaces.txt ~/download/
但出現錯誤:
scp: /home/kuba/Pobrane/file: No such file or directory
scp: that: No such file or directory
scp: have: No such file or directory
scp: spaces.txt: No such file or directory
我也嘗試file\\ that\\ have\\ spaces.txt
過file%20that%20have%20spaces.txt
答案1
SSH 呼叫伺服器上的 shell(無法繞過它)。 scp 呼叫此 shell 並告訴它需要寫入的檔案的名稱。 scp 的設計方式是將您作為檔案名稱傳遞的任何內容直接插入到遠端 shell 命令中。這意味著,如果檔案名稱中有任何 shell 特殊字元(對於典型的 Unix shell 來說意味著空格)!"#$&'()*-;<=>?@[\]^`{|}~
(其中一些取決於shell 和名稱中的位置),則需要將它們引用兩次:一次用於本地shell,一次用於引用它們。
這有優點,特別是它允許您指定通配符。它還允許您使用~
遠端主目錄(但檔案名稱是相對於遠端主目錄的,因此您可以使用[email protected]:download/…
而不是[email protected]:~/download/…
)。但缺點是當檔案名稱包含特殊字元時您需要小心。如果您想要過濾伺服器上允許的檔案名稱(尤其是沒有 shell 命令權限的受限帳戶),您還需要小心。
引用兩次的簡單方法是在整個名稱周圍使用單引號,並在需要在遠端保護的每個特殊字元之前使用反斜線。這不適用於檔案名稱中的單引號;轉義那些為四個字元'\''
。在你的例子中:
scp '[email protected]:download/file\ that\ have\ spaces.txt' ~/download/
您使用兩個反斜線的嘗試不起作用,因為\\
本地 shell 將其解析為反斜線後跟分隔參數的空格;您需要將反斜線-空格傳送到遠端主機,而反斜線和空格都需要保護不被本機shell解析,因此兩者前面都需要一個反斜線,即您需要3個反斜線和一個空格。
scp [email protected]:download/file\\\ that\\\ have\\\ spaces.txt ~/download/
SFTP 不會通過 shell,因此這是避免特殊字元問題的一種方法。SSHFS基於 SFTP 建置並提供直接遠端檔案訪問,因此您可以執行以下操作
mkdir remote
sshfs [email protected]: remote
cp remote/download/file\ that\ have\ spaces.txt ~/download/
fusermount -u remote
rmdir remote
答案2
解決方案是同時使用引號和轉義空格:
scp "[email protected]:~/download/file\ that\ have\ spaces.txt" ~/download/