SSHを使用してファイルをアップロードし、ユーザーに制御権限を再付与します。

SSHを使用してファイルをアップロードし、ユーザーに制御権限を再付与します。

SSHを使用してリモートサーバーに接続するときに、スクリプトが内容を確認してstdinに戻る前にプライベートスクリプトを展開するスクリプトを作成しようとしています。これはすべて1つのSSH接続内で行われます。それ以外の場合は、何度も実行する必要があります。認証のために..)。

動作するスクリプトがあります。

#!/bin/zsh
HOST="$1"

# Install ZSH if it's not already installed
ssh "$HOST" <<- EOF
    if [ ! -x /bin/zsh ]; then
        if [ -x "/usr/bin/dnf" ]; then
            sudo dnf install -y zsh >/dev/null
        elif [ -x "/usr/bin/apt-get" ]; then
            sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh >/dev/null
        fi
    fi
EOF

# Copy ZSH configuration to remote host
tar -cz -f - -C "$HOME" --exclude="*.zwc" {.zshrc,.zshenv,.config/zsh/{p10k.zsh,plugins}} | ssh "$HOST" 'tar -xz -f - -C "$HOME"'

# Login with ZSH in a login shell
ssh -t "$HOST" 'SHELL=/bin/zsh /bin/zsh -l'

ただし、これには複数の接続を使用します。 1つの接続だけをどのように使用できますか?

POCを試しました

#!/bin/zsh
HOST="$1"

# redirect 3 to standard output
exec 3>&1

ssh -t $HOST >&3 <&1 &

# doesn't work, doesnt execute on remote host
echo "hostname"
# this as well
echo "hostname" >&1

# works, give back the tty of the remote server to the user
exec 1<&0

wait
echo "THE END"

ただし、ttyが返されるまでリモートサーバーからコマンドを実行することはできません。そして、ファイルを送信する方法もわかりません。

これをすべて行う方法はありますか?

ベストアンサー1

同じストリームを介してシェルコード、tarファイル、およびユーザー入力を送信するには、潜在的にパスワードまたはキーパスワードのフレーズが必要ですが、ssh -t非常sshに不器用で脆弱です。

confファイルが大きすぎず、環境変数を受け入れることができ、リモートsshdのAcceptEnv LC_*構成に1つがある場合(通常の場合)、次のbase64のいずれかにエンコードされたtgzファイルを渡すことができます。

#! /bin/zsh -
HOST=${1?}

LC_ZC=$(
  tar -cz -f - -C ~ --exclude="*.zwc" {.zshrc,.zshenv,.config/zsh/{p10k.zsh,plugins}} |
    base64
) exec ssh -o SendEnv=LC_ZC -t "$HOST" '
  if ! command -v zsh; then
    if command -v dnf; then
      sudo dnf install -y zsh
    elif command -v apt-get; then
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh
    fi
  fi > /dev/null

  echo "$LC_ZC" | base64 -d | tar -zxf - -C ~
  unset -v LC_ZC
  SHELL=/bin/zsh exec /bin/zsh -l'

(また、リモートシステム上のユーザーのログインシェルがPOSIXに似ているとします。)

そうでない場合、最も簡単な方法はおそらく複数の呼び出しを使用することsshですが、すべて接続多重機能を使用して同じログインセッションを共有することです(ControlMaster//マニュアルページの指示および/またはこのサイトの例を参照)。ControlPathControlPersist

最新バージョンのopensshを使用する別の方法は、-R remote_socket:local_socketUnixドメインソケットを使用してtarファイルを転送することです(zsh/net/socket例:zshモジュールを使用)。

おすすめ記事