regexmakefilegrep

using grep inside make to check if a file contains an export to PATH


I'd like a make function that checks if the given path is already exported in my .bashrc/.zshrc/etc. file.

Since you have to double and triple escape things (shell + make + regex) I got stuck. My current attempt:

define ensure_in_path
    @rg='export\s+PATH\s*=\s*\"\\$$PATH:${1}\"'; \
    if ! cat "${1}" | /bin/grep -q -E $$rg ; then \
        echo "added \"${2}\" to exports in \"${1}\".";\
    fi
endef

What I would like to match something like this export\s+=\s*\"?\$PATH:<the path here>\". (Is this even a good match?)

Example:

$(call ensure_in_path,$$HOME/.bashrc,$$HOME/.local/bin) should check if export PATH="$PATH:/home/<username>/.local/bin" is in /home/<username>/.bashrc and if not append it to it.

It would of course be nice to also expand the paths inside .bashrc before checking them, but that's a question for another day.

Edit 1:

Working bash version:

pth="$HOME/.local/bin"
rg="export\s+PATH\s*=\s*\"?\\\$PATH:${pth}\"?"
cat $HOME/.bashrc | grep -qE $rg

Still not working make version:

define ensure_in_path
    @rg="export\s+PATH\s*=\s\"?\\\\$$PATH:${2}\"?"; \
    echo $$rg;\
    if cat "${1}" | /bin/grep -qE $$rg ; then \
        echo "added path..."; \
    fi 
endef

It's not escaping $PATH correctly.


Solution

  • Well, the version in the makefile you show above, is not the same at all as the one in the shell script. I'm not sure why you decided to make extra changes. For example, you added an extra backslash. But you're making things more difficult for yourself by using double-quotes; there's no need for double-quotes when you're using make variables because make just expands its variables regardless of where they appear.

    Also just to point out, it's illegal in a shell script to put whitespace around the = when assigning a variable. VAR=foo is valid; VAR = foo is illegal.

    If this works in a shell script:

    grep -qE 'export\s+PATH="?$PATH:$HOME/.local/bin"?' < $HOME/.bashrc
    

    then the equivalent of this for a makefile (where $1 is $HOME/.bashrc and $2 contains $HOME/.local/bin would be:

    grep -qE 'export\s+PATH="?$$PATH:$2"?' < $1