String 生成包含变量值的bash字符串,该变量值用单引号括起来
我做了一个噩梦,因为这是最琐碎的任务 我的最终目标是从bash脚本发出以下命令:String 生成包含变量值的bash字符串,该变量值用单引号括起来,string,bash,variables,quote,String,Bash,Variables,Quote,我做了一个噩梦,因为这是最琐碎的任务 我的最终目标是从bash脚本发出以下命令: sqlite3 my\u db.db'。读取my\u file.sql' 这里有两个陷阱: 1.单引号是必须的,不能用双引号代替 2. my_file.sql是一个只有在运行时才知道的变量 所以我需要的是一种让bash构建一个字符串的方法,该字符串一方面包含一个变量值,另一方面该值应该用单引号括起来 我还更喜欢不依赖额外工具(如AWK、Perl等)的解决方案。如果真的有必要的话,也许是塞德 谢谢 谢谢乔纳森和纳尔
sqlite3 my\u db.db'。读取my\u file.sql'
这里有两个陷阱:1.单引号是必须的,不能用双引号代替
2.
my_file.sql
是一个只有在运行时才知道的变量
所以我需要的是一种让bash构建一个字符串的方法,该字符串一方面包含一个变量值,另一方面该值应该用单引号括起来
我还更喜欢不依赖额外工具(如AWK、Perl等)的解决方案。如果真的有必要的话,也许是塞德
谢谢
谢谢乔纳森和纳尔逊 我尝试了这三个建议,但都失败了。
为了简单起见,我将问题归结为以下几点:
#/bin/bash
文件=/tmp/1
ls““$file””
ls\'$file\'
ls“$file”
$touch/tmp/1
$ls'/tmp/1'
/tmp/1
$。/tst.sh
“/tmp/1”:没有这样的文件或目录
“/tmp/1”:没有这样的文件或目录
“/tmp/1”:没有这样的文件或目录
VAR=my_file.sql
VAR2="'.read $VAR'"
sqlite3 my_db.db $VAR2
这将实现您希望执行的操作(为程序获取单引号),但它使用双引号:
sqlite3 my_db.db "'".read" "my_file.sql"'"
避免双引号,您可以编写:
sqlite3 my_db.db \'.read\ my_file.sql\'
对于这两个参数,sqlite3
将第二个参数视为包含以下内容的字符串:
'.read my_file.sql'
如果文件名位于变量(file=my_file.sql
)中,则:
如果文件名包含空格,这些符号很容易混淆
然而,我不认为这是你真正想要的。禁止双引号的规定令人费解,单引号的要求也同样令人费解。单引号不是强制性的。以下所有命令都使用完全相同的参数运行sqlite3:
sqlite3 my_db.db '.read my_file.sql'
sqlite3 my_db.db ".read my_file.sql"
sqlite3 my_db.db .read\ my_file.sql
sqlfile="my_file.sql"
sqlite3 my_db.db ".read $sqlfile"
在所有情况下,在将参数传递给sqlite3之前,都会解析并删除引号(/escape)。这就是你想要的。您希望sqlite3获得两个参数:my_db.db
和。请阅读my_file.sql
。您不希望sqlite3看到命令周围的引号——这相当于:
$ sqlite3 my_db.db
SQLite version 3.7.7 2011-06-25 16:35:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> '.read my_file.sql'
...>
…正如您所看到的,这让sqlite3感到困惑
顺便说一句,这与ls示例中的问题相同:您将单引号作为参数的一部分传递给ls,因此它正在查找名称中包含单引号的文件,而没有找到它。您希望shell删除引号,而不是将其作为参数的一部分传递给命令。好的,问题解决了 缺少的只是在行之前添加一个小的“eval”命令。
因此,在我给出的简单示例脚本中,更改:
ls“$file”
to:eval ls“$file”
完成了任务
感谢所有回复者:-)user1860085,如果您查看了sqlite3命令的文档,并且您将了解shell如何处理引号和空格,您可能会得出结论,您希望在案例中使用双引号 但如果您真的想要单引号,以下是解决方案:
eval sqlite3 my_db.db \'.read $VARIABLE\'
飞行中的哪个将更改为:
sqlite3 my_db.db '.read my_file.sql'
但是我不明白你为什么想要它…为什么单引号是必须的?这应该是单引号中的一个参数还是两个参数,一个以单引号开始,另一个以单引号结束。谢谢戈登-这是我不知道的重要信息。不过,我的问题比sqlite3语法更广泛,这在主题中可以看到。我相信我的最后一个答案在很多其他情况下都会对其他人有所帮助。@user1860085:深呼吸,理解这里的一些评论者反复试图解释的内容:你在解决错误的问题,你需要理解shell的引用机制。对于这个清晰的答案+1。啊,不!eval的主要目的是创建无法理解的bug。如果你确切知道自己在做什么,它可以安全地使用,但这不是那种情况。哈哈,对不起,无意冒犯;-)您能否详细说明您提到的eval的问题性质,以及它将如何影响我的解决方案(似乎正在工作…)?它显示了如何去除两层引号,但最终结果与
ls“$file”
完全相同。在需要引号的情况下,它与ls“$file”并不相同。例如,在我最初的示例中,它在失败时工作。您在这里所做的是在命令周围添加单引号,然后使用eval
删除它们。说真的,这是eval
在这里做的唯一一件事。如果它还做了什么,那就是坏事。在这种特殊情况下,eval
只会在文件名包含单引号时引起问题(在这种情况下,sqlite3无论如何都会有问题),但您最好首先避免这个问题。是什么让你觉得你需要单引号?我敢肯定,您在使用sqlite3 my_db.db.read$file“
时遇到的任何问题都不是因为缺少单引号。也不是因为没有变量sqlite3 my_db.db“'。read my_file.sql'
但我怀疑这是否真的是解决方案,尽管这正是OP所要求的。
sqlite3 my_db.db '.read my_file.sql'