リモートサーバーに接続し、パッケージがインストールされているかどうかを確認するスクリプトがあります。
ssh root@server 'bash -s' < myscript.sh
myscript.sh:
OUT=`rpm -qa | grep ntpdate`
if [ "$OUT" != "" ] ; then
echo "ntpdate already installed"
else
yum install $1
fi
この例は簡略化できます。ここは myscript2.sh
同じ問題があります:
read -p "Package is not installed. Do you want to install it (y/n)?" choise
私の問題は、bashが私の答えをインタラクティブに読み取ることができないことです。
ユーザーにプロンプトを表示する機能を失うことなくローカルスクリプトをリモートで実行する方法はありますか?
このようなものを試してください:
_$ ssh -t yourserver "$(<your_script)"
_
_-t
_はttyの割り当てを強制し、$(<your_script)
はファイル全体を読み取り、この場合、コンテンツを1つの引数としてssh
に渡します。これは、リモートユーザーのシェルによって実行されます。
スクリプトにパラメーターが必要な場合は、スクリプトの後にパラメーターを渡します。
_$ ssh -t yourserver "$(<your_script)" arg1 arg2 ...
_
それは普遍的かどうかはわかりませんが、私にとってはうまくいきます。
あなたの問題は、ssh
がリモートマシンで非対話型のログインシェルを起動することです。明らかに簡単な解決策は、スクリプトをリモートサーバーにコピーして、そこから実行することです。
scp myscript.sh root@server:/tmp && ssh root@server /tmp/myscript.sh
何らかの理由でコピーできない場合は、スクリプトを変更して最初に接続し、$1
がインストールされているかどうかを確認してから、必要に応じて再接続してインストールします。
OUT=$(ssh root@server rpm -qa | grep "$1");
if [ "$OUT" != "" ] ; then
echo "$1 already installed"
else
read -p "Package $1 is not installed. Do you want to install it (y/n)?" choice
if [ "$choice" -eq "y" ]; then
ssh root@server yum install "$1"
fi
fi
これが良い 説明 です。
だから私はスクリプトを
hostname
echo -n "Make your choice :"
read choice
echo "You typed " ${choice}
echo done
そして、これはうまくいきませんでした。
スクリプトをリモートに移動して、sshでのローカルリダイレクトを回避しました。 (私のコマンドはfという名前のファイルにあります)
cat f | ssh [email protected] 'cat >remf'
ssh user@remotehost bash remf
これはうまくいきました。これが出力です:
christian@clafujiu:~/tmp$ ssh localhost bash tmp/f
christian@localhost's password:
Linux clafujiu 2.6.32-52-generic #114-Ubuntu SMP Wed Sep 11 19:00:15 UTC 2013 i686 GNU/Linux
Sun Nov 10 14:58:56 GMT 2013
Make your choice :abc
You typed abc
done
@terdonが元々の意図はローカルスクリプトをリモートで実行することであると述べたように、リモートコピーは自動化できます。これはすべて1行での1つの例にすぎません。
REMID=`cat f |ssh user@remotehost 'cat > remf_$$; echo $$'` ;ssh [email protected] "bash remf_${REMID} ; rm -v remf_${REMID}"
私は過去に何度かこの問題の解決策を探しましたが、完全に満足のいくものを見つけることはできませんでした。 sshに接続すると、対話性が失われます。 2つの接続(scp/ssh)は遅く、一時ファイルはそのままにしておく可能性があります。そして、コマンドラインのスクリプト全体は、しばしば地獄から逃れることになります。
最近、コマンドラインバッファーのサイズが通常かなり大きいことに気付きました( 'getconf ARG_MAX> 2MB私が見たところ)。そして、これを使用して、これをどのように使用し、脱出する問題を軽減できるかについて考えました。
結果は次のとおりです。
ssh -t <Host> /bin/bash "<(echo "$(cat my_script | base64 | tr -d '\n')" | base64 --decode)" <arg1> ...
またはヒアドキュメントと猫を使用する:
ssh -t <Host> /bin/bash $'<(cat<<_ | base64 --decode\n'$(cat my_script | base64)$'\n_\n)' <arg1> ...
このアイデアを拡張して、完全に機能するBASHサンプルスクリプト sshx
を作成し、引数をssh経由でローカル入力ファイルにすることもできます(BASHだけでなく)。 。 こちら を参照してください。