如何停止 bash 引用报价?
how to stop bash quoting quotes?
我想 运行 一个小的 bash 脚本,但是我在引号周围添加了额外的垃圾。
我以为使用单引号 '
会给我一个文字字符串?
我使用 set +x
来查看脚本的实际作用。
代码是这样的:
set -x
task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; " '
echo $task
$task
当我 运行 我会看到:
▶ bin/run-local.sh
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; " '
+ echo mysql --port=3336 --host=127.0.0.1 -u root training_service -e '"DELETE' FROM 'expert_bundle_claim;' '"'
mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; "
+ mysql --port=3336 --host=127.0.0.1 -u root training_service -e '"DELETE' FROM 'expert_bundle_claim;' '"'
mysql Ver 14.14 Distrib 5.6.47, for osx10.15 (x86_64) using EditLine wrapper
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
然后是错误。
所以基本上实际的 SQL 命令 "DELETE FROM expert_bundle_claim; "
被破坏为 '"DELETE' FROM 'expert_bundle_claim;' '"'
。
我试过把 '
和 "
inner/outer 颠倒过来,结果更乱了。
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e '\'' DELETE FROM expert_bundle_claim; '\'' '
+ mysql --port=3336 --host=127.0.0.1 -u root training_service -e ''\''' DELETE FROM 'expert_bundle_claim;' ''\'''
尝试了另一种方法,只是用 < filename.sql
管道进入 mysql,但它被插入到引用的 '<'
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service < ./bin/revert_tasks.sql'
+ mysql --port=3336 --host=127.0.0.1 -u root training_service '<' ./bin/revert_tasks.sql
有什么建议可以最好地处理这个问题并防止插值吗?
不要将代码存储在变量中。获得正确的报价是一场噩梦。改用函数。您可以像往常一样编写代码,而无需任何特殊的引用或转义。
task() {
mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; "
}
task
您的尝试无效的原因是 Bash 的扩展规则。当像 $task
这样的变量被扩展时,Bash 不会解析扩展产生的引号。它只查看原始命令行中的引号。扩展产生的引号被视为文字字符,就好像它们是用 \"
或 '"'
.
转义的一样
有关详细信息,请参阅:
我想 运行 一个小的 bash 脚本,但是我在引号周围添加了额外的垃圾。
我以为使用单引号 '
会给我一个文字字符串?
我使用 set +x
来查看脚本的实际作用。
代码是这样的:
set -x
task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; " '
echo $task
$task
当我 运行 我会看到:
▶ bin/run-local.sh
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; " '
+ echo mysql --port=3336 --host=127.0.0.1 -u root training_service -e '"DELETE' FROM 'expert_bundle_claim;' '"'
mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; "
+ mysql --port=3336 --host=127.0.0.1 -u root training_service -e '"DELETE' FROM 'expert_bundle_claim;' '"'
mysql Ver 14.14 Distrib 5.6.47, for osx10.15 (x86_64) using EditLine wrapper
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
然后是错误。
所以基本上实际的 SQL 命令 "DELETE FROM expert_bundle_claim; "
被破坏为 '"DELETE' FROM 'expert_bundle_claim;' '"'
。
我试过把 '
和 "
inner/outer 颠倒过来,结果更乱了。
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service -e '\'' DELETE FROM expert_bundle_claim; '\'' '
+ mysql --port=3336 --host=127.0.0.1 -u root training_service -e ''\''' DELETE FROM 'expert_bundle_claim;' ''\'''
尝试了另一种方法,只是用 < filename.sql
管道进入 mysql,但它被插入到引用的 '<'
+ task='mysql --port=3336 --host=127.0.0.1 -u root training_service < ./bin/revert_tasks.sql'
+ mysql --port=3336 --host=127.0.0.1 -u root training_service '<' ./bin/revert_tasks.sql
有什么建议可以最好地处理这个问题并防止插值吗?
不要将代码存储在变量中。获得正确的报价是一场噩梦。改用函数。您可以像往常一样编写代码,而无需任何特殊的引用或转义。
task() {
mysql --port=3336 --host=127.0.0.1 -u root training_service -e "DELETE FROM expert_bundle_claim; "
}
task
您的尝试无效的原因是 Bash 的扩展规则。当像 $task
这样的变量被扩展时,Bash 不会解析扩展产生的引号。它只查看原始命令行中的引号。扩展产生的引号被视为文字字符,就好像它们是用 \"
或 '"'
.
有关详细信息,请参阅: