"Exporting" a function using export -f
creates an environment variable with the function body. Consider this example:
$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() { echo \'\"\ \ \$
}
This means that only the shell (just Bash?) will be able to accept the function. You could also set the function yourself as the Bash only considers envvars starting with () {
as function:
$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'
If you need to "export" this variable over SSH, then you really need the function as a string. This can be done with the print option (-p
) for functions (-f
) of the declare
built-in:
$ declare -pf fn
fn ()
{
echo \'\"\ \ \$
}
This is very useful if you have more complex code that needs to be executed over SSH. Consider the following fictitious script:
#!/bin/bash
remote_main() {
local dest="$HOME/destination"
tar xzv -C "$dest"
chgrp -R www-data "$dest"
# Ensure that newly written files have the 'www-data' group too
find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh user@host "$(declare -pf remote_main); remote_main"
#!/bin/sh
to#!/bin/bash
and afterdoit() {...}
justexport -f doit
#!/bin/sh
too, but it is good practice to use#!/bin/bash
so that you avoid problems when the default shell is not bash.