glad to write it for you here. I've done a lot of searching about that and haven't found a solution. What I want to do is relatively simple.

There is a caveat local bash function in my workstation environment.

function caveat(){
  echo "function main caveat executing in $HOSTNAME"

  function caveat_a(){
    echo "function caveat_a executing in $HOSTNAME"

  function caveat_b(){
    echo "function caveat_b executing in $HOSTNAME"

And I would like do SSH into a remote host (in a interactive shell) to do some lazy sysadmin tasks there. And when I need to execute either caveat_a or caveat_b functions I would like to be able to call them there, into the remote host..

What my research revealed is that is possible to declare a local function to be available remotely and then execute it directly ... and it works fine for me. But what I need is to declare and fall into an interactive shell.

Last attempt was to include a 'bash --login' in the end of the line, as shown below:

username@localhost ~ $ caveat
function main caveat executing in localhost
username@localhost ~ $ caveat_a
function caveat_a executing in localhost
username@localhost ~ $ caveat_b
function caveat_b executing in localhost
username@localhost ~ $
username@localhost ~ $ ssh username@remote_host -t "$(declare -f caveat); caveat; caveat_a; bash --login"
Are you sure you want to continue connecting (yes/no)? yes
username@remote_host's password: 
function main caveat executing in remote_host
function caveat_a executing in remote_host
username@remote_host ~ $ #nice, it executed those caveat functions as echoed above

..this way it interacts with me.. so I can execute other commands there.. but when I press 'caveat<TAB><TAB>' my caveat is not declared there yet.

I think I'm missing something. Thanks in advance for all your help and answers.

If possible, it seems better to use vanilla solution as simple as possible (without expect, without other binaries).


1 Answer 1


Try this:

ssh -t user@host "$(declare -f caveat); export -f caveat; exec bash -li"

Thanks to @Scott for the excellent advice.

The -t option for ssh is required to allow the interactive shell full access to your terminal's capabilities.

exec bash -li launches an interactive login shell. Since the function was exported, it will be available in this new shell.

  • Isn’t it possible to combine that with what the OP already has and do ssh username@remote_host -t "$(declare -f caveat); export -f caveat; exec bash -li"? Dec 11, 2017 at 20:42
  • @Scott, yes, awesome. I was testing with a remote user that does not user bash as the login shell. Dec 11, 2017 at 21:11
  • Worked like a charm for me too! Thanks a lot. Thanks glenn jackman and @Scott Dec 12, 2017 at 0:19
  • what if the sysadmin don't have only one caveat(){} but instead he has a bunch of __docker_*(){} functions? Would it possible to declare and export all of those functions prefixed with __docker_<something> Dec 12, 2017 at 0:22
  • 1
    In that case I would put the functions in a file (with the export commands), upload it with scp, and source it in the ssh command Dec 12, 2017 at 2:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .