2016-08-15 55 views
1

我喜欢把我的连接和一般的转储设置成变量,然后养活他们mysqldump像这样:奇bash的行为

# echo mysqldump ${SRC_SRV} ${SRC_SQL_OPT} 
mysqldump -u root -pPass -h host --where="COL > '2016-08-14' AND COL <= '2016-08-15'" --opt --single-transaction --skip-triggers --no-create-db --no-create-info dbase table 

有我bash变量:

WHERE="COL > '2016-08-14' AND COL <= '2016-08-15'" 
SRC_SQL_OPT="--where=\"${WHERE}\" --opt --single-transaction --skip-triggers --no-create-db --no-create-info ${DB} ${TBL}" 

请注意,当我echo - 这一切似乎都很正常,但如果我尝试在bash中运行它,我收到一个错误:

mysqldump: Got error: 1049: Unknown database '>' when selecting the database 

这里的原因(bash -x)的原因:

+ mysqldump -u root -pPass -h host '--where="COL' '>' ''\''2016-08-14'\''' AND COL '<=' ''\''2016-08-15'\''"' --opt --single-transaction --skip-triggers --no-create-db --no-create-info dbase table 

注:现在有一堆周围--where选项额外的单引号...... 如何

回答

1

$SRC_SQL_OPT包含以下字符串:

--where="COL > '2016-08-14' AND COL <= '2016-08-15'" --opt --single-transaction --skip-triggers --no-create-db --no-create-info dbase table 

当扩大mysqldump ${SRC_SRV} ${SRC_SQL_OPT}该字符串,猛砸拆分其internal field separator变量到单独的参数。

因为默认情况下,字段分隔符是空白,$SRC_SQL_OPT大干快上拆分每出现的空白,不论报价或不内发生的空间。人们可以防止猛砸从分裂变量引述他们,但因为你真正想要的是其他地方变量分裂,你要么需要:

  • 分离出其中的一部分(如@Pianosaurus has said),例如:

    WHERE="COL > '2016-08-14' AND COL <= '2016-08-15'" 
    SRC_SQL_OPT="--opt --single-transaction --skip-triggers --no-create-db --no-create-info ${DB} ${TBL}" 
    
    mysqldump $SRC_SRV --where="$WHERE" $SRC_SQL_OPT 
    
  • 使用不同的内部字段分隔符,例如:

    WHERE="COL > '2016-08-14' AND COL <= '2016-08-15'" 
    SRC_SRV="-u;root;-pPass;-h;host" 
    SRC_SQL_OPT="--where=\"$WHERE\";--opt;--single-transaction;--skip-triggers;--no-create-db;--no-create-info;$DB;$TBL" 
    
    IFS=';' mysqldump $SRC_SRV $SRC_SQL_OPT 
    
1

您的第一个命令与您可能使用的bash变量版本之间存在显着差异。

当您运行诸如第一个代码块中的命令之类的命令时,双引号将被bash自身解释,并将内容作为单个参数发送到该命令。

在你的bash变量中,你明确插入了一个文字引号。使bash按照你想要的方式进行解析的唯一方法是使用eval命令,因为它在引号内部和外部都包含空格。

在bash中最简单的方法是在命令中避免使用这种嵌套变量。在你的情况下,在运行该命令之前不要制造SRC_SQL_OPT。或者至少,不包括--where-部分。