【问题标题】:Using Bash script to check string length during compilation在编译期间使用 Bash 脚本检查字符串长度
【发布时间】:2015-11-08 09:27:22
【问题描述】:

我试图在编译期间检查目标名称(在 Makefile 中定义)。例如,如果目标名称的名称超过 10 个字符,则编译过程中止,并抛出错误消息“目标名称超过 10 个字符”。

部分代码:

TARGETNAME:
@if [ ${#TARGET_NAME} -ge 10 ]; then \ 
echo "TARGET name exceeds 10 chars"; \
exit; \
fi

然后当我尝试编译时,make TARGETNAME,我收到一条错误消息:

/bin/sh: line 0: [: -ge: unary operator expected

我不确定这个 Makefile 是用 Bash 还是其他语言编写的。语法看起来像是在 Bash 脚本中,但我在代码中没有看到像 SHELL := /bin/bash 这样的命令。

感谢大家的帮助,问题解决了

【问题讨论】:

  • 1. 10后留空间。2.将ercho替换为echo。
  • @SMA 我在这篇文章中打错了字,但在代码中它和你说的完全一样。
  • 如果之前@在做什么?你能发布实际的脚本(如果它很大,也可以是其中的一部分)
  • @IgnacioVazquez-Abrams 我对使用 bash 脚本的 makefile 完全陌生。我用它来获取 TARGETNAME 的长度,并将其与 10 进行比较。
  • @M.S 那不是 Bash。那是有效的 Bourne shell,或等效的。错误甚至说/bin/sh@ 是一个制造的东西。

标签: bash compilation makefile


【解决方案1】:

你可能想要这样的东西:

TARGETNAME:
    t=$@ && [ $${#t} -lt 10 ] || { echo "Target name $$t has 10 or more chars"; false; }

编辑。看来你并没有真正理解这件事。请做以下小实验:在一个空目录中,创建一个名为Makefile 的文件,内容如下:

short:
    t=$@ && [ $${#t} -lt 10 ] || { echo "Target name $$t has 10 or more chars"; false; }

longtargetname:
    t=$@ && [ $${#t} -lt 10 ] || { echo "Target name $$t has 10 or more chars"; false; }

然后,从这个目录中:

$ make short
t=short && [ ${#t} -lt 10 ] || { echo "Target name $t has 10 or more chars"; false; }
$ make longtargetname 
t=longtargetname && [ ${#t} -lt 10 ] || { echo "Target name $t has 10 or more chars"; false; }
Target name longtargetname has 10 or more chars
make: *** [longtargetname] Error 1

看到了吗?该行在执行之前打印(这是make 的默认值)。您可以通过在行前添加 @ 来禁用打印。

在 GNU make 中,如果你想要更精致的东西,你可以定义一个函数:

define check_length
    @t=$@; \
    if [ $${#t} -ge 10 ]; then \
        echo "Target name $$t has 10 or more chars"; \
        false; \
    fi
endef

short:
    $(call check_length,$@)

longtargetname:
    $(call check_length,$@)

【讨论】:

  • 这一行打印将被打印出来而不是执行。这个 Makefile 可能不是 Bash 脚本,我正在添加更多代码。
  • @M.S:你试过了吗?只需将我写的行放在一个空的 Makefile 中并运行makemake TARGETNAME。这里的关键点是使用t=$@ 将Makefile 变量传输到shell。您也可以将目标名称TARGETNAME 替换为模板%
  • 感谢您的反对!如果您认为此答案错误或无用,请发表评论……也许我可以改进它(也许我会在此过程中学到一些东西)。
  • 感谢您的帮助,我已经尝试了您的代码。它只是被打印出来,而不是被执行。这是否意味着这个 Makefile 是用不同的语言编写的?顺便说一句,我没有拒绝你的回答。
  • @M.S 你说的它只是被打印出来,没有被执行是什么意思?执行了!你会看到它打印在你的终端输出上,因为这是make 的默认值。在行前加上 @ 以禁用打印:@t=$@ && [ $${#t} -lt 10 ]... 此代码是用 make 的语言编写的。
【解决方案2】:

${#TARGET_NAME} 是对名称为 #TARGET_NAMEMakefile 变量 的引用(可能无效)。如果这是未定义的(除非您找到了创建疯狂 Makefile 变量名称的方法),那么在 shell 上下文中评估的语句是 if [ -ge 10 ]; then,这会导致您看到的错误。您需要使用if [ $${#TARGET_NAME} -ge 10 ]; then,这将导致${#TARGET_NAME} 在shell 上下文中被处理..

【讨论】:

  • if [ $${#TARGET_NAME} -ge 10 ],修复了错误信息,但无论我在 if 语句中设置什么条件,编译都会继续。
  • 那么看来问题不一样了,你应该用minimal, complete and verifiable example再发一个问题,尽快查明真相。
猜你喜欢
  • 2011-10-20
  • 2018-05-12
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 2013-01-23
  • 2015-06-23
  • 1970-01-01
  • 2012-06-18
相关资源
最近更新 更多