我有一个 bash 脚本:
#!/bin/bash
set -x
PATH=/bin:/sbin:/usr/bin:/usr/sbin
server="$1"
curdate=$(date +'%Y%m%d')
sshoptions="-i /root/.ssh/backup -q -t"
mysqluser="root"
mysqlpassword=$(ssh $sshoptions root@$server "cat /root/.my.passwd")
mysqlaccess="-u$mysqluser -p$mysqlpassword"
mysqldatabases=$(ssh $sshoptions root@$server "mysql $mysqlaccess -B -N -e \"SHOW DATABASES;\" | grep -E -v 'information_schema|mysql'")
mysqldump="mysqldump $mysqlaccess --opt --skip-comments -B -R"
for db in $mysqldatabases; do
echo "$(date +"%Y/%m/%d %H:%M:%S") mysqldump: dump $db"
ssh $sshoptions root@$server "$mysqldump $db" | gzip -9 > $db_$curdate.sql.gz
done
如您所见,它用于 MySQL 数据库的备份(我计划将它与 rsnapshot 一起使用)。
当我运行此脚本时出现一个问题:
# bash /etc/rsnapshot.scripts/mysql.sh sugar.dev.host.com
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin
+ server=sugar.dev.host.com
++ date +%Y%m%d
+ curdate=20130321
+ sshoptions='-i /root/.ssh/backup -q -t'
+ mysqluser=root
++ ssh -i /root/.ssh/backup -q -t [email protected] 'cat /root/.my.passwd'
+ mysqlpassword=XXXXXX
+ mysqlaccess='-uroot -pXXXXXX'
++ ssh -i /root/.ssh/backup -q -t [email protected] 'mysql -uroot -pXXXXXX -B -N -e "SHOW DATABASES;" | grep -E -v '\''information_schema|mysql'\'''
+ mysqldatabases=$'sugarcrm\r'
+ mysqldump='mysqldump -uroot -pXXXXXX --opt --skip-comments -B -R'
+ for db in '$mysqldatabases'
++ date '+%Y/%m/%d %H:%M:%S'
' echo '2013/03/21 17:41:04 mysqldump: dump sugarcrm
2013/03/21 17:41:04 mysqldump: dump sugarcrm
+ gzip -9
' ssh -i /root/.ssh/backup -q -t [email protected] 'mysqldump -uroot -pXXXXXX --opt --skip-comments -B -R sugarcrm
因此,我得到了从解析的 SQL 查询中获得的 '\r' 符号。我在转储中看到此错误:
mysqldump:出现错误:1102:选择数据库时数据库名称“sugarcrm^M”不正确
我该如何正确地修剪它?我说的“正确”是指我们不能立即修剪“mysqldatabases”变量的值。因为这里有一个数据库,但如果有两个或更多,stdout 就会出错。所以我的观点是,我们必须在“for”循环中修剪符号。
请建议一个正确的方法。谢谢。
答案1
另外一种方式:
sed
for db in '$mysqldatabases'; do
db=$(echo $db|sed 's/\r$//')
bash 本机
for db in '$mysqldatabases'; do
db=${db//\r/}
答案2
我将首先尝试对 mysql 使用原始参数--raw 或 -r。
--raw,-r 对于表格输出,列周围的“装箱”可启用一列 值来区分。对于非表格输出(如 就像在批处理模式下生成的那样,或者当 --batch 或 --silent 选项 给定),特殊字符会在输出中被转义,以便它们可以 很容易识别。换行符、制表符、NUL 和反斜杠都写在 如 \n、\t、\0 和 \\。--raw 选项可禁用此字符 逃跑。 以下示例演示了表格输出与非表格输出 并使用原始模式来禁用转义: %mysql mysql> 选择 CHAR(92); +----------+ | 字符(92) | +----------+ | \ | +----------+ %mysql-s mysql> 选择 CHAR(92); 字符(92) \\ %mysql-s-r mysql> 选择 CHAR(92); 字符(92) \
如果这不起作用我会用 tr 删除它们例如
tr -d '\r'
答案3
\r
(又名,^M
正如您所发现的)是回车符(ASCII 控制字符 CR)。某些操作系统将其用作行尾的一部分,例如 Windows 以\r\n
(CR、NL,如 ASCII 所预期的那样)结束行,Mac 以 结束行\n\r
,而 Unix 创建者凭借其无穷智慧,通过以 结束行节省了一个字节\n
。因此,您在 Unix/Linux 上按照 Windows/DOS 约定处理文本。有一个名为 的工具dos2unix
可以修复行尾(在 Fedora 中,该软件包名为dos2unix
)。请小心,仅仅剥离\r
可能会损坏(二进制)文件。