2012-02-28 145 views
3

我試圖讀取一個文件包含文件路徑逐行並scp文件到另一臺服務器,但由於文件名中的某些字符像'(',')','&'等我需要逃避輸入:轉義bash變量中的特殊字符

input.txt中

/folder1/folderA/filename+(oh+how+nice,+parantheses) 

script.sh

#!/bin/sh 

promote_to=random.server.com 
dev_catalog=/folderX/ 
uat_catalog=/folderY/ 

while read line 
do 
uat_path=$(echo "$uat_catalog$line" | sed -e "s/(/\\\(/g" | sed -e "s/)/\\\)/g") 
dev_path=$(echo "$dev_catalog$line" | sed -e "s/(/\\\(/g" | sed -e "s/)/\\\)/g") 

scp $dev_path [email protected]$promote_to:$uat_path 
scp $dev_path".atr" [email protected]$promote_to:$uat_path".atr" 
done < "input.txt" 

輸出

-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory 
-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory 
usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] 
       [-l limit] [-o ssh_option] [-P port] [-S program] 
       [[[email protected]]host1:]file1 [...] [[[email protected]]host2:]file2 
ssh: random.server.com: Name or service not known 
lost connection 

任何形式的幫助表示讚賞。

回答

7

這裏的部分問題是,本地和遠程文件名的解析方式不同:直接使用本地文件名,因此您唯一需要做的就是將其放在雙引號中(如@ Ignacio的答案),但是遠程文件名被傳遞給一個遠程shell,它通過另一層解析(引用和轉義移除等)來運行它。所以,你想添加逃生到遠程路徑只有。我也採取了簡化sed命令一點點的自由:

#!/bin/sh 

promote_to=random.server.com 
dev_catalog=/folderX/ 
uat_catalog=/folderY/ 

while read line 
do 
uat_path="$(echo "$uat_catalog$line" | sed -e 's/[()&]/\\&/g')" 
dev_path="$dev_catalog$line" 

scp "$dev_path" "[email protected]$promote_to:$uat_path" 
scp "$dev_path.atr" "[email protected]$promote_to:$uat_path.atr" 
done < "input.txt" 

注意,sed模式我也用過,'s/[()&]/\\&/g',只逃脫括號和&符號;如果您的文件名包含任何其他shell元字符,請務必將它們添加到[]中的字符列表中。

+0

非常感謝您的詳細解答! – 2012-02-29 08:02:04

0

您試圖執行/folder1/folderA/filename+(oh+how+nice,+parantheses)作爲命令。相反,你可能打算做echo /folder1/folderA/filename+(oh+how+nice,+parantheses) | ...

編輯:@Ignacio說什麼。

+0

這是正確的......錯過了回聲,但仍然不起作用:「/ folder1/folderA /文件名+ \\(oh + how + nice,+ parantheses \\):沒有這樣的文件或目錄」 – 2012-02-28 14:10:08

+0

刪除一個但是每個sed的反斜槓都會拋出:「bash:-c:line 0:接近意外標記的語法錯誤'(' bash:-c:line 0:'scp -t bash:-c:line 0:令牌'(' bash:-c:第0行:'scp -t/folder1/folderA /文件名+(oh + how + nice,+ parantheses)' 丟失連接「 – 2012-02-28 14:14:11