我正在做一个应该是最微不足道的任务的噩梦。
我的最终目标是从bash脚本发出以下命令:
sqlite3 my_db.db '.read my_file.sql'
这里有两个捕获:
1.单引号是强制性的,不能用双引号替换
2. my_file.sql
是仅在运行时才知道的变量。
所以我需要的是一种让bash构建一个字符串的方法,一方面包含一个变量值,另一方面该值应该用单引号括起来。
我也更喜欢不依赖AWK,Perl等其他工具的解决方案。如果真的有必要,也许是sed。
感谢。
感谢Jonathan和Nelson。
我尝试了所有三个建议,但都失败了 为简单起见,我将问题简化为以下内容:
我写了以下脚本(tst.sh):
#!/bin/bash
file=/tmp/1
ls "'"$file"'"
ls \'$file\'
ls "'$file'"
然后我提出以下命令:
$ touch /tmp/1
$ ls '/tmp/1'
/tmp/1
$ ./tst.sh
'/tmp/1': No such file or directory
'/tmp/1': No such file or directory
'/tmp/1': No such file or directory
似乎确实添加了引号,但结果命令与手动输入时的命令不同。
有什么想法吗?
答案 0 :(得分:1)
单引号不必须。所有以下命令都使用完全相同的参数运行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
和.read 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删除引号,而不是将它们作为参数的一部分传递给命令。答案 1 :(得分:0)
您可以执行以下操作:
VAR=my_file.sql
VAR2="'.read $VAR'"
sqlite3 my_db.db $VAR2
答案 2 :(得分:0)
这将按照您的意思执行(获取程序的单引号),但它使用双引号:
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 my_db.db "'".read" "$file"'"
sqlite3 my_db.db \'.read\ $file\'
如果文件名包含空格,这些符号很容易混淆。
但是,我不认为这可能是你真正想要的。双引号的禁令令人费解,单引号的要求同样令人费解。
答案 3 :(得分:0)
user1860085,如果您查看 sqlite3 命令的文档,并且您将知道shell如何处理引号和空格,您可能会得出结论,您需要双引号用于您的情况。
但是如果你真的想要单引号,这里有解决方案:
eval sqlite3 my_db.db \'.read $VARIABLE\'
飞行中的将变为:
sqlite3 my_db.db '.read my_file.sql'
但我不明白为什么你会想要它......
答案 4 :(得分:-2)
所有缺失的是添加一点“评估”。行前命令。
因此,在我给出的简单示例脚本中,更改:
ls "'$file'"
至:
eval ls "'$file'"
做了这个工作。
感谢所有回复者: - )