本文介绍了转义bash变量中的特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试逐行读取包含文件路径的文件,并将文件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

感谢任何形式的帮助。

推荐答案

这里的部分问题是本地和远程文件名的解析方式不同:本地文件名是直接使用的,所以您唯一需要做的就是用双引号将其括起来(就像@Ignacio的答案一样),但是远程文件名会被传递到远程外壳,该外壳通过另一层解析来运行它(引号和转义删除等)。因此,您只想将转义添加到远程路径。我还冒昧地稍微简化了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'只转义圆括号和与号;如果您的文件名包含任何其他外壳元字符,请确保将它们添加到[]中的字符列表中。

这篇关于转义bash变量中的特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 13:45