如何在Makefile Target中使用bash regex [英] How to use bash regex inside Makefile Target

查看:54
本文介绍了如何在Makefile Target中使用bash regex的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在bash脚本中,以下正则表达式似乎运行良好:

In a bash script, the following regex appears to work well:

MY_STRING="FirstName-LastName-Gender-Age"
MY_REGEX="([^-]+)-([^-]+)$"
if [[ $MY_STRING =~ $MY_REGEX ]]; then
    echo "Match: $BASH_REMATCH"
fi

我对在Makefile中使用此脚本感兴趣.它似乎有语法问题.例如:

I'm interested in using this script inside the Makefile. It appears to have syntax issues. For example:

my-target:
    MY_STRING="FirstName-LastName-Gender-Age"
    MY_REGEX="([^-]+)-([^-]+)$"
    if [[ $MY_STRING =~ $MY_REGEX ]]; then
        echo "Match: $BASH_REMATCH"
    fi

make中正确的语法是什么?上面的内容似乎与变量分配有关,正则表达式中与"$"有关,等等.

What would be the correct syntax for this in make? The above appears to have issues with variable assignment, issues with the "$" in the regex, etc.

推荐答案

您在这里遇到很多问题.第一个是make不会调用bash作为其外壳,而是调用/bin/sh (POSIX外壳).在许多系统上,这是指向bash的链接,但在许多其他系统上,则是到破折号或某些其他POSIX shell的链接.如果您在makefile配方中尝试使用这种bash-ism,则makefile不可移植.您可以根据需要将 SHELL:=/bin/bash 添加到makefile中,以强制make始终使用bash ...但是在无法使用bash的地方,它将失败.

You have many problems here. The first one is that make doesn't invoke bash as its shell, it invokes /bin/sh (POSIX shell). On many systems that is a link to bash, but on many other systems it's a link to dash or some other POSIX shell. If you try to use bash-isms like this in your makefile recipes your makefile is not portable. You can, if you like, add SHELL := /bin/bash to your makefile to force make to use bash always... but it will fail anywhere that bash isn't available.

第二个问题是,make在单独的shell中调用配方的每个逻辑行.按照这种方式编写,每个变量赋值都在一个新的Shell中创建,然后该Shell退出并且该赋值丢失.此外,仅if语句的第一行被发送到shell,这显然是语法错误.您需要在换行符之前使用反斜杠,以确保整个脚本是一条逻辑行并发送到同一外壳程序...这意味着您还需要添加分号以在需要的地方换行.

The second problem is that make invokes each logical line of your recipe in a separate shell. The way you have this written, every variable assignment is created in a new shell, then the shell exits and that assignment is lost. Further, only the first line of the if-statement is sent to a shell which is clearly a syntax error. You need to use backslashes before your newline to ensure the entire script is one logical line and is sent to the same shell... and that means you need to add semicolons to break lines where needed, as well.

即使在shell脚本中,也可能会怀疑 MY_REGEX 的分配,因为您在双引号字符串中具有未转义的美元符号.但是它碰巧对您有用,因为美元符号后面没有字符可能是变量.不过,为了安全起见,您应该在此处使用单引号字符串.

Even in a shell script, the assignment of MY_REGEX is suspect because you have an unescaped dollar sign in a double-quoted string. However it happens to work for you because there's no character after the dollar sign that could be a variable. Nevertheless you should be using single-quoted strings here to be safe.

最后,美元符号( $ )是特殊制作的,因此,如果要将 $ 传递给外壳,则必须对其进行转义.Make使用两个美元符号 $$ 来逃脱单个美元符号.

And finally, dollar signs ($) are special to make, so if you want to pass a $ to the shell you have to escape it. Make uses two dollar signs $$ to escape a single dollar sign.

因此,您的makefile应该如下所示:

So, your makefile should look like this:

SHELL := /bin/bash

my-target:
        MY_STRING="FirstName-LastName-Gender-Age"; \
        MY_REGEX='([^-]+)-([^-]+)$$'; \
        if [[ $$MY_STRING =~ $$MY_REGEX ]]; then \
            echo "Match: $$BASH_REMATCH"; \
        fi

我个人将其重写为使用标准工具,而不是依赖bash等.但这就是您的要求.

Personally I would rewrite this to use standard tools rather than relying on bash etc. but that's your call.

这篇关于如何在Makefile Target中使用bash regex的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆