あるコンピュータから別のコンピュータにssh -tを使用してコマンドを実行できることを発見しました。
その後、次のタスクを実行して、コンピュータのログファイルを一対で追跡するスクリプトを作成できる必要があると思いました。
ssh -t $1 ssh -t $2 tailf /pathtofile/$3/log.log
実際に1,2,3を手動で入力すると正常に動作します。
私の問題は、これを行うには1、2、または3つのホスト間を移動する必要があるかもしれません。
zshでどうすればいいですか?ちょっと掘り下げてみると変身が私の友達のようですが少し混乱します。
答え1
私は実際のユーザーではないので、ソリューションzsh
を作成しますsh
(zsh
しなければならない実行も可能です)
一般的なポイントは、ssh -t hostname
最後の項目を除く各コマンドラインオプションに対して1ビットのリストを作成し、そのリストをコマンドとして実行することです。
#!/bin/sh
argn=$#
i=0
for arg do
shift
i=$(( i + 1 ))
if [ "$i" -lt "$argn" ]; then
set -- "$@" ssh -t "$arg"
else
set -- "$@" "/pathtofile/$arg/log.log"
fi
done
command "$@"
次のように実行してください。
sh script.sh alpha beta gamma zeta
リストが作成されます
ssh -t alpha ssh -t beta ssh -t gamma /pathtofile/zeta/log.log
スクリプトの最後のコマンドはコマンドとして実行されます。
このリストは、$@
スクリプトの先頭にあるスクリプトのコマンドライン引数を含む場所引数リストに組み込まれています。ループは、元のリストの最後の要素がいつ見つかったかを追跡し、それを特別に処理します。
このset
コマンドを上記のように使用すると、リストに追加され、リストのshift
最初の要素(現在作業中の要素)が削除されます。
zsh
特定の構文を使用すると、このコンテンツをより短くてエレガントにすることができると確信しています。
答え2
私はあなたがループから簡単に出ることができないと思います。
cmd=()
for i ($argv[1,-2]) cmd+=(ssh -t $i)
$cmd tailf /pathtofile/$argv[-1]/log.log
厳密に言うと、渡すシェルコマンドラインなので、これらの任意の値をサポートできるようにするには、これらのパラメータを引用し、ssh
各sshに引用レベルを追加する必要があります。$1
$2
ここでは、すべてのホストのユーザーログインシェルがBourneに似ていると仮定します。
cmd=(tailf /pathtofile/$argv[-1]/log.log)
argv[-1]=()
while (($#argv)) {
cmd=(ssh -t "$argv[-1]" ${(j: :)${(qq)cmd}})
argv[-1]=()
}
これにより、呼び出し時に機能します。
that-script host1 host2 'dir with spaces and other nasty characters'