1

I have a file sedstr.sh containing a function sedstr:

#!/bin/bash
function sedstr {
# From stackoverflow.com/a/29626460/633251 (Thanks Ed!)
    old="$1"
    new="$2"
    file="${3:--}"
    escOld=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$old")
    escNew=$(sed 's/[&/\]/\\&/g' <<< "$new")
    sed -i.tmp "s/\<$escOld\>/$escNew/g" "$file" # added -i.tmp
    echo "sedstr done"
}

I have an external file "test" to be edited in place with these contents:

My last name is Han.son and I need help.
If the makefile works, I'll have a new last name.

I want to call the sedstr function with its arguments from a makefile. Nothing should be returned, but the external file should be edited. Here is a small makefile that doesn't work:

all: doEdit

doEdit:
  $(shell ./sedstr.sh) # I was hoping this would bring the function into the scope, but nay
  $(shell sedstr 'Han.son', 'Dufus', test)

How can I call this function using variables in the makefile? The error is:

make: sedstr: Command not found
make: Nothing to be done for `all'.
10
  • Why have the commands in a function? Commented Jul 13, 2015 at 1:57
  • @EtanReisner Thank you. The extra $(shell ... ) was left over from when the line was not in a target. So I removed that and the extra commas (silly), now I have ./sedstr.sh; sedstr 'Hans.son' 'Dufus' test and it gives the following error: MWE2:7: *** missing separator. Stop. With the $(shell ... ) I get the error I originally reported. Commented Jul 13, 2015 at 2:08
  • @MikkelChristiansen Having the function externally was suggested in a another question as a more sensible approach. Commented Jul 13, 2015 at 2:09
  • What was the missing separator? Commented Jul 13, 2015 at 2:28
  • I had used spaces instead of tab (obviously new to this). Commented Jul 13, 2015 at 2:29

2 Answers 2

4

Each line in a make recipe is executed in its own shell.

Similarly, so is each call to $(shell).

They don't share state.

To do what you want ould would need a recipe line of

$(shell . ./sedstr.sh; sedstr 'Han.son' 'Dufus' test)

That being said there's no reason to use $(shell) here at all as you are already in a shell context and as you can just as easily (and more correctly) use a recipe line of

. ./sedstr.sh; sedstr 'Hans.son' 'Dufus' test

And yes, the commas in the original are just incorrect.

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for the advice on the 'big picture'. If I use the direct approach, it complains /bin/sh: sedstr: command not found which is not the shell I thought I was using...
make uses /bin/sh by default but that's not really relevant here. The second attempt here had a typo, you need to source the script and not run it as a script on its own.
Got it, error eliminated, but it doesn't carry out the editing. I'm doubting the function now, see my comments above under the original question. Thanks for you help.
I got it working now. No problem with the sedstr function. Seemed to be a problem with crossing my test functions and test files, and also, unsaved edits were not being seen in testing. Thanks for your help.
No, ./sedstr.sh runs the script as a script. So the function only exists in the shell context of the script that ends immediately when the file ends. . loads the script in the current shell context. Look for source in the bash man page.
|
1

You can call the function from inside sedstr.sh. At the end

sedstr "$1" "$2" "$3"

EDIT Or see other answer

6 Comments

I assume I put that after the function definition. What do I put in the makefile?
./sedstr.sh 'Hans.son' 'Dufus' test
OK, I did it as you said, and I get this result: ./sedstr.sh 'Hans.son' 'Dufus' test; sedstr done which seems reasonable. A test.tmp file is created as expected, but the file contents are not edited. So... maybe the function isn't working?
I notised Han.son in test and Hans.son as argument?
Ugh... too tired. Thanks. But fixing that didn't lead to an edited file. I'm checking to make sure I've got it all correct.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.