I've searched for solutions to this problem several times in the past, however never finding a fully satisfactory one. Piping into ssh looses your interactivity. Two connects (scp/ssh) is slower, and your temporary file might be left lying around. And the whole script on the command line often ends up in escaping hell.

Recently I encountered that the command line buffer size is usually quite large ('getconf ARG_MAX > 2MB where I looked). And this got me thinking about how I could use this and mitigate the escaping issue.

The result is:

 ssh -t <host> /bin/bash "<(echo "$(cat my_script | base64 | tr -d '\n')" | base64 --decode)" <arg1> ...


or using a here document and cat:

 ssh -t <host> /bin/bash $'<(cat<<_ | base64 --decode\n'$(cat my_script | base64)$'\n_\n)' <arg1> ...


I've expanded on this idea to produce a fully working BASH example script [`sshx`][1] that can run arbitrary scripts (not just BASH), where arguments can be local input files too, over ssh. See [here][1].


 [1]: https://gist.github.com/sourcesimian/933b26f4e8ff516959f9890387bcd512