How to use bash regex inside Makefile Target

对着背影说爱祢 提交于 2021-02-09 17:42:55

问题


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

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

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.


回答1:


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.

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.

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.

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.

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

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



来源:https://stackoverflow.com/questions/48365305/how-to-use-bash-regex-inside-makefile-target

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!