我有一个makefile,我用它来运行简单的bash脚本在一个repo我正在工作。我正试图使一个新的使呼叫将我登录到我的mySQL数据库自动。我有我的用户名和密码存储在一个.zinfo文件在一个已知的位置(如"/u/r/z/myid/.zinfo")。我正在尝试读取该文件的行来获取我的密码,其格式为:
user = csj483
database = cs495z_csj483
password = fjlID9dD923
这是我试图从makefile运行的代码,但它不工作。如果我直接在shell中运行相同的代码,它似乎可以正常工作。注意,我必须使用双$$s,因为make不喜欢单$s。
login:
for line in $$(cat /u/z/users/cs327e/$$USER/.zinfo);
do
PASSWORD=$$line;
echo $$PASSWORD;
done
echo $$PASSWORD
在这一点上,我只是试图获得密码,这应该是password在循环中设置的最后一个值。如果有人能建议一种更简单的方法来检索密码,或者指出我的代码中的错误,我将不胜感激。最后,我还希望检索数据库名称,如果有任何帮助,我也将不胜感激。我是bash新手,但对许多其他语言都有经验。
你没有说明你说的"不工作"是什么意思;当你问问题的时候,请一定要清楚你输入的命令,你得到的结果(剪切和粘贴是最好的),以及为什么这不是你所期望的。
无论如何,您看到的最有可能的行为是第一个回显显示了您期望的输出,但第二个没有。这是因为make
将在单独的shell中调用配方中的每个逻辑行。因此,for循环在一个shell中运行,它设置了环境变量PASSWORD
,然后该shell退出,最后一个echo
在一个新的shell中运行…其中PASSWORD
不再设置。
您需要将整个命令行放在配方中的单个逻辑行中:
login:
for line in $$(cat /u/z/users/cs327e/$$USER/.zinfo); do
PASSWORD=$$line;
echo $$PASSWORD;
done
&& echo $$PASSWORD
最后要记住的一件事:您说您正在运行bash脚本,但是make 而不是运行bash。不管您个人使用什么shell,它都运行/bin/sh
(想象一下,如果makefiles使用了用户碰巧使用的任何shell,会造成多大的破坏!)最好的选择是用可移植shell语法编写菜谱。如果您确实不能这样做,请确保在Makefile
中设置SHELL := /bin/bash
以强制make使用bash。
埃塔:
关于你的大问题,你有很多选择。如果您可以控制zinfo文件的格式,那么我强烈建议您使用与shell相同的语法来定义变量。在上面的示例中,如果您删除=
符号周围的空白,如下所示:
user=csj483
database=cs495z_csj483
password=fjlID9dD923
那么你就有了一个具有变量赋值的有效shell脚本。现在你可以在你的makefile中找到这个脚本,你的生活非常简单:
login:
. /u/z/users/cs327e/$$USER/.zinfo
&& echo user is $$user
&& echo database is $$database
&& echo password is $$password
如果您无法控制zinfo文件的语法,那么生活会更困难。你可以使用eval,像这样:
login:
while read var eq value; do
eval $$var="$$value";
done < /u/z/users/cs327e/$$USER/.zinfo
&& echo user is $$user
&& echo database is $$database
&& echo password is $$password
这个版本只在"="周围有空格的情况下才有效。如果你想同时支持这两种功能,那也是可以的。