我试图逐行读取包含文件路径的文件并将文件scp到另一台服务器,但由于文件名中的某些字符如'(',') ','&'我需要逃避输入:
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 user@$promote_to:$uat_path
scp $dev_path".atr" user@$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]
[[user@]host1:]file1 [...] [[user@]host2:]file2
ssh: random.server.com: Name or service not known
lost connection
感谢任何形式的帮助。
答案 0 :(得分:9)
这里的部分问题是本地和远程文件名的解析方式不同:本地文件名是直接使用的,所以你唯一需要做的就是用双引号括起来(如@ 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" "user@$promote_to:$uat_path"
scp "$dev_path.atr" "user@$promote_to:$uat_path.atr"
done < "input.txt"
请注意,我使用的sed
模式's/[()&]/\\&/g'
仅绕过括号和&符号;如果您的文件名包含任何其他shell元字符,请务必将它们添加到[]
中的字符列表中。
答案 1 :(得分:0)
您尝试执行/folder1/folderA/filename+(oh+how+nice,+parantheses)
作为命令。您可能打算改为echo /folder1/folderA/filename+(oh+how+nice,+parantheses) | ...
。
编辑:@Ignacio说的是什么。