diff --git a/docs/kittens/ssh.rst b/docs/kittens/ssh.rst index 836a38923..bdbe4a2d0 100644 --- a/docs/kittens/ssh.rst +++ b/docs/kittens/ssh.rst @@ -114,9 +114,9 @@ the TTY, any other requests are responded to by errors. .. note:: When connecting to BSD servers, it is possible the bootstrap script will - fail or run slowly, because they are crippled in various ways. Your best bet - is to install python on the server, make sure the login shell is something - POSIX sh compliant, not csh, and use :code:`python` as the :opt:`interpreter + fail or run slowly, because the default shells are crippled in various ways. + Your best bet is to install python on the server, make sure the login shell + is something POSIX sh compliant, and use :code:`python` as the :opt:`interpreter ` in :file:`ssh.conf`. .. include:: /generated/conf-kitten-ssh.rst diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py index 31c01f201..41906e3bc 100644 --- a/kittens/ssh/main.py +++ b/kittens/ssh/main.py @@ -407,10 +407,11 @@ def wrap_bootstrap_script(sh_script: str, interpreter: str) -> List[str]: unwrap_script = '''"import base64, sys; eval(compile(base64.standard_b64decode(sys.argv[-1]), 'bootstrap.py', 'exec'))"''' else: # We cant rely on base64 being available on the remote system, so instead - # we quote the bootstrap script by replacing ' and \ with \v and \f and - # surrounding with ' - es = "'" + sh_script.replace("'", '\v').replace('\\', '\f') + "'" - unwrap_script = r"""'eval "$(echo "$0" | tr \\\v\\\f \\\047\\\134)"' """ + # we quote the bootstrap script by replacing ' and \ with \v and \f + # also replacing \n and ! with \r and \b for tcsh + # finally surrounding with ' + es = "'" + sh_script.replace("'", '\v').replace('\\', '\f').replace('\n', '\r').replace('!', '\b') + "'" + unwrap_script = r"""'eval "$(echo "$0" | tr \\\v\\\f\\\r\\\b \\\047\\\134\\\n\\\041)"' """ return [interpreter, '-c', unwrap_script, es] diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 97785e2cd..f48df6c3b 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -412,6 +412,36 @@ exec_with_shell_integration() { esac } +execute_sh_with_posix_env() { + if [ "$login_shell" != "/bin/sh" ]; then return 1; fi + if command "$login_shell" -l -c ":" > /dev/null 2> /dev/null; then return 1; fi + if [ -z "$shell_integration_dir" ]; then + if [ -n "$KITTY_SSH_KITTEN_DATA_DIR" ]; then + shell_integration_dir="$HOME/$KITTY_SSH_KITTEN_DATA_DIR/shell-integration" + else + die "The data directory is not defined, ssh kitten cannot function." + fi + fi + sh_dir="$shell_integration_dir/sh" + if [ ! -d "$sh_dir" ]; then mkdir -p "$sh_dir" || die "Creating data directory failed"; fi + # Source /etc/profile, ~/.profile, and then check and source ENV + echo ' +if [ -n "$KITTY_SH_INJECT" ]; then + unset ENV; unset KITTY_SH_INJECT + _ksi_safe_source() { if [ -f "$1" -a -r "$1" ]; then . "$1"; return 0; fi; return 1; } + if [ -n "$KITTY_SH_POSIX_ENV" ]; then export ENV="$KITTY_SH_POSIX_ENV"; fi + unset KITTY_SH_POSIX_ENV + _ksi_safe_source "/etc/profile"; _ksi_safe_source "${HOME-}/.profile" + if [ -n "$ENV" ]; then _ksi_safe_source "$ENV"; fi +fi' > "$sh_dir/login_shell_env.sh" + export KITTY_SH_INJECT=1 + if [ -n "$ENV" ]; then + export KITTY_SH_POSIX_ENV="$ENV" + fi + export ENV="$sh_dir/login_shell_env.sh" + exec "$login_shell" +} + # Used in the tests TEST_SCRIPT @@ -422,10 +452,14 @@ case "$KITTY_SHELL_INTEGRATION" in ;; (*) # not blank - q=$(printf "%s" "$KITTY_SHELL_INTEGRATION" | command grep '\bno-rc\b') - if [ -z "$q" ]; then - exec_with_shell_integration - # exec failed, unset + if [ -n "$shell_integration_dir" ]; then + q=$(printf "%s" "$KITTY_SHELL_INTEGRATION" | command grep '\bno-rc\b') + if [ -z "$q" ]; then + exec_with_shell_integration + # exec failed, unset + unset KITTY_SHELL_INTEGRATION + fi + else unset KITTY_SHELL_INTEGRATION fi ;; @@ -437,4 +471,5 @@ esac [ "$(exec -a echo echo OK 2> /dev/null)" = "OK" ] && exec -a "-$shell_name" $login_shell execute_with_python execute_with_perl +execute_sh_with_posix_env exec $login_shell "-l"