2012-02-28 54 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