0

So, I was playing around with this answer, when I found that neither

printf_stdin () {
    read input
    printf "$input"
}

sed "/lorem ipsum foobar/ {
   s/'/'\"'\"'/g
   s/\(lorem ipsum \)\(foobar\)/\1'\"\$(printf '%s' '\2' | printf_stdin)\"'/g
   s/.*/printf '%s' '\0'/e
}" <<< "lorem ipsum foobar"

nor

printf_ () {
    printf "$1"
}

sed "/lorem ipsum foobar/ {
   s/'/'\"'\"'/g
   s/\(lorem ipsum \)\(foobar\)/\1'\"\$(printf_ '\2')\"'/g
   s/.*/printf '%s' '\0'/e
}" <<< "lorem ipsum foobar"

works. They both output the error sh: 1: <bash function>: not found. I'm not planning to use this thing anymore, but still, I'm curious why this doesn't work and how to fix it.

Edit

Running

sed "/lorem ipsum foobar/ {
   s/'/'\"'\"'/g
   s/\(lorem ipsum \)\(foobar\)/\1'\"\$(printf '%s' '$0')\"'/g
   s/.*/printf '%s' '\0'/e
}" <<< "lorem ipsum foobar"

gives

lorem ipsum /bin/bash

so sed seems to be invoking the bash shell and not the bourne shell?

3
  • What is your operating system? Is your /bin/sh bash or is it dash? Or something else? Commented Nov 16 at 12:58
  • If you want to do stuff combining sed, shell, function calls, etc then do yourself a favour and just use perl. It'll be easier, far more capable, faster, and you won't end up getting lost in a maze of twisty little quotation marks. Simple example: echo bar | perl -pe 'BEGIN{sub myfoo {my $str = shift; return "foo $str"}}; s/.*/myfoo $&/e' (sure, this trivial example doesn't need the /e modifier OR a function, but it does illustrate what's possible and how much easier it is than doing it in shell). people try to do too much in shell, a language that makes easy things needlessly difficult. Commented Nov 16 at 14:35
  • What is your /bin/sh? Is it perhaps a symlink to bash? Does this work if you run export -f printf_stdin before your first command? Commented Nov 17 at 16:33

2 Answers 2

2

sed runs shell commands in a sub-shell of the default system shell i.e. whatever /bin/sh links to (Usually a POSIX shell like dash) that shell doesn't support exporting user defined functions (which is needed in this case) i.e. printf_stdin () {...;} is defined in the current running shell (parent) and is called from a subshell (child) where that function isn't available/defined hence sh: 1: <function>: not found... That's why AFAIK.

5
  • Hm I investigated your hypothesis, and it seems that sed runs the subshell $( ... ) as a bash shell? See the appended section titled "Edit", which I just appended. Commented Nov 16 at 8:22
  • @Grass in your edit $0 is expanded by the shell on the command line before it gets passed to sed so passed as a string ... Try something simple sed 's/.*/printf "%s\n" $0/e' <<<'blabla' instead. Commented Nov 16 at 8:31
  • Oh I see, thanks! That's pretty interesting. Would it be possible to switch to a bash shell from within the bourne shell? Commented Nov 16 at 8:34
  • @Grass I don't know if that is practically possible for sed (aside from changing the default system shell which is a bad idea and asking for trouble) ... However, making sed run Bash instead is not enough as the function defined in the parent shell needs to be exported export -f printf_stdin as the latter is the real culprit. Commented Nov 16 at 8:55
  • I see, thanks! This was interesting. Commented Nov 16 at 9:02
1

Without the shebang selecting /bin/bash, your system selects /bin/sh, an older, simpler shell, that doesn't understand the bashisms you use.

Before your file's first line,

#!/bin/bash

will tell the system to use bash, rather than sh, to interpret your script.

2
  • Nope. My default shell is bash, plus I ran the above with a bash shebang, as you suggested, before posting my question. The same error is produced. Commented Nov 16 at 8:20
  • 2
    If you ran your script with a specific shebang then include that in the code in your question so we don't waste time diagnosing issues caused by a missing shebang. Commented Nov 16 at 15:11

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.