psql doesn't pass on exported shell environment functions

Started by David G. Johnstonalmost 9 years ago10 messagesgeneral
Jump to latest
#1David G. Johnston
david.g.johnston@gmail.com

In hindsight I'm not surprised but couldn't find a ready explanation on the
web and figured I'd inquire here. In short: "export VAR" and "export -f
functionname" behave differently when psql is acting as a relay.

//main-script
#!/usr/bin/env bash

function testfunction() {
echo "Function Test"
}
export TEST_ENVVAR='Test'
export -f testfunction

psql "service=postgres" <<SQL
\! ./psql-call-bash
SQL

./psql-call-bash

//psql-call-bash script
#!/usr/bin/env bash

echo "Enter"
echo "EnvVar: $TEST_ENVVAR"
echo "Invoking Function..."

testfunction

exit

// command (after making both the above executable)

./main-script > output.txt 2>&1

//output.txt

Enter
EnvVar: Test
Invoking Function...
./psql-call-bash: line 7: testfunction: command not found
Enter
EnvVar: Test
Invoking Function...
Function Test

I was really hoping the first output block would match the second,
specifically the "Function Test" line being present instead of
"./psql-call-bash: line 7: testfunction: command not found"

Apparently exported variables go someplace different than exported
functions :(

I don't suppose this is something that can be fixed in psql...

David J.

#2Laurenz Albe
laurenz.albe@cybertec.at
In reply to: David G. Johnston (#1)
Re: psql doesn't pass on exported shell environment functions

David G. Johnston wrote:

In hindsight I'm not surprised but couldn't find a ready explanation on the web and
figured I'd inquire here. In short: "export VAR" and "export -f functionname" behave
differently when psql is acting as a relay.

It works for me on Linux with 9.6.3 psql:

laurenz:~> cat psql-call-bash
#!/usr/bin/env bash

echo "Enter"
echo "EnvVar: $TEST_ENVVAR"
echo "Invoking Function..."

testfunction

exit
laurenz:~> chmod 0700 psql-call-bash
laurenz:~> function testfunction() { echo "Function Test"; }
laurenz:~> export -f testfunction
laurenz:~> export TEST_ENVVAR='Test'
laurenz:~> psql
Border style is 2.
Line style is unicode.
psql (9.6.3)
Type "help" for help.

test=> \!
laurenz:~> ./psql-call-bash
Enter
EnvVar: Test
Invoking Function...
Function Test

Yours,
Laurenz Albe

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#3David G. Johnston
david.g.johnston@gmail.com
In reply to: Laurenz Albe (#2)
Re: psql doesn't pass on exported shell environment functions

​On Fri, Jul 7, 2017 at 3:59 AM, Albe Laurenz <laurenz.albe@wien.gv.at>
wrote:

David G. Johnston wrote:

In hindsight I'm not surprised but couldn't find a ready explanation on

the web and

figured I'd inquire here. In short: "export VAR" and "export -f

functionname" behave

differently when psql is acting as a relay.

It works for me on Linux with 9.6.3 psql:

​Except you haven't recreated the scenario I presented.​

​You only are involving a single script and that script defines
"testfunction" itself (which makes exporting pointless). In my example the
script being executed within the psql script does not define testfunction
itself.

-> == execute in subshell

​main-script (def func) -> psql -> psql-call-bash (invoke func)

David J.

#4Laurenz Albe
laurenz.albe@cybertec.at
In reply to: David G. Johnston (#3)
Re: psql doesn't pass on exported shell environment functions

David G. Johnston wrote:

It works for me on Linux with 9.6.3 psql:

​Except you haven't recreated the scenario I presented.​

​You only are involving a single script and that script defines "testfunction" itself
(which makes exporting pointless). In my example the script being executed within the
psql script does not define testfunction itself.

-> == execute in subshell

​main-script (def func) -> psql -> psql-call-bash (invoke func)

I am confused; my shell script does *not* contain a function definition.

I copied and pasted a shell session:

First, show the script that contains a function invocation.
Then, define and export the function.
Then, call psql
Then, escape to a subshell.
Then, call the script that successfully calls the function.

Am I missing something?

Yours,
Laurenz Albe

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Laurenz Albe (#4)
Re: psql doesn't pass on exported shell environment functions

Albe Laurenz <laurenz.albe@wien.gv.at> writes:

David G. Johnston wrote:

​Except you haven't recreated the scenario I presented.​

Am I missing something?

I wonder what platform David is using. This looks suspiciously like
a feature that macOS' SIP would be designed to break.

It would be interesting to capture the output of "env" in the sub-shell
to see which environment variables and functions are getting through.

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#6David G. Johnston
david.g.johnston@gmail.com
In reply to: Laurenz Albe (#4)
Re: psql doesn't pass on exported shell environment functions

On Fri, Jul 7, 2017 at 7:43 AM, Albe Laurenz <laurenz.albe@wien.gv.at>
wrote:

David G. Johnston wrote:

It works for me on Linux with 9.6.3 psql:

​Except you haven't recreated the scenario I presented.​

​You only are involving a single script and that script defines

"testfunction" itself

(which makes exporting pointless). In my example the script being

executed within the

psql script does not define testfunction itself.

-> == execute in subshell

​main-script (def func) -> psql -> psql-call-bash (invoke func)

I am confused; my shell script does *not* contain a function definition.

Am I missing something?

​Nope, it was a combination of ERRNOCAFFINE and not seeing a second script.

​I'm using Ubuntu 16.04

I tried your way of not using a "main-script" and got the same result.

I can see the exported environment variable TEST_ENVVAR in the "env" output
of the psql \! subshell. "declare -Fx" shows no results.

I replaced "/usr/bin/env bash" with "/bin/bash" to no effect.

David J.

#7David G. Johnston
david.g.johnston@gmail.com
In reply to: David G. Johnston (#6)
Re: psql doesn't pass on exported shell environment functions

On Fri, Jul 7, 2017 at 8:12 AM, David G. Johnston <
david.g.johnston@gmail.com> wrote:

​I'm using Ubuntu 16.04

​Seems to be a regression since this works on my 14.04 setup.

David J.

#8David G. Johnston
david.g.johnston@gmail.com
In reply to: David G. Johnston (#7)
Re: psql doesn't pass on exported shell environment functions

On Fri, Jul 7, 2017 at 8:19 AM, David G. Johnston <
david.g.johnston@gmail.com> wrote:

On Fri, Jul 7, 2017 at 8:12 AM, David G. Johnston <
david.g.johnston@gmail.com> wrote:

​I'm using Ubuntu 16.04

​Seems to be a regression since this works on my 14.04 setup.

​Sorry for the append but my 14.04 setup is using 9.5 while the 16.04 setup
is using 9.6.

David J​.

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#6)
Re: psql doesn't pass on exported shell environment functions

"David G. Johnston" <david.g.johnston@gmail.com> writes:

​I'm using Ubuntu 16.04

Hmph. Works for me on RHEL6. I'm betting that Ubuntu has put in some
weird security restriction, possibly an overreaction to the "shellshock"
bug which was in the exported-functions feature.

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#10David G. Johnston
david.g.johnston@gmail.com
In reply to: Tom Lane (#9)
Re: psql doesn't pass on exported shell environment functions

On Fri, Jul 7, 2017 at 8:45 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

"David G. Johnston" <david.g.johnston@gmail.com> writes:

​I'm using Ubuntu 16.04

Hmph. Works for me on RHEL6. I'm betting that Ubuntu has put in some
weird security restriction, possibly an overreaction to the "shellshock"
bug which was in the exported-functions feature.

​Thank you both for looking at this. While my curiosity is still piqued
I've solved the original problem without resorting to exporting a function
through a psql invocation. Fortunately, exported functions are still seen
by directly called bash scripts​ so a few other areas where I leverage that
feature are still working.

I've haven't totally discounted local configuration interplay here - my
bashrc is non-trivial and there a few differences between the setups
besides versions - though a security enhancement in 16.04 seems plausible.

David J.