
ssh
here-documentを使用してリモート ホスト上でコマンドを実行する簡単なスクリプトがあります。
コマンドラインでワンライナーで実行しようとしましたが、スクリプト外でヒアドキュメントを実行する方法がわかりませんでした。 可能ですか? ヒアドキュメントについてグーグルで検索したりドキュメントを読んだりして時間を費やしましたが、わかりませんでした。
このスクリプトは正常に動作します。SSH 経由でリモートで実行するには here-document セクションが必要でしたawk
が、通常は簡単なものにはワンライナーを使用するのが好きです。
#!/bin/bash
# it looks up all my hosts with 'db' in the name
# then gets the PID of any rsyncs running as user 'research'
# and pumps them into xargs
getHosts=(`curl --silent "http://assetts.lab/all_hosts" | grep -v ^# | awk -F" " '{print$1}'|grep db`)
for BOX in ${getHosts[@]};do
echo "$BOX: "
ssh -T sshUser@$BOX <<"EOF"
ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i ps -fp '{}'
#ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i kill '{}'
EOF
echo
done
おそらく何か簡単なことを見逃しているのでしょう... とにかく、何か提案があればよろしくお願いします :)
答え1
ヒアドキュメントの使用について何かする必要は特にないと思うが、するスクリプト内の他の部分をかなり簡素化できることがわかります (これにより、ヒアドキュメントは不要になります)。
まず、getHosts
配列を設定するためのパイプラインを簡素化し (grep
にパイプする理由はほとんどありませんawk
)、配列全体を削除できます。
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
# rest of code
done
grep
ここでは、 ++コマンドawk
をgrep
1 つのコマンドに結合しました。また、ホスト名を中間変数に格納するのではなく、コマンドでループに直接入力するようawk
にしました。awk
ループ内では、ユーザーに属するrsync
またはプロセスに関する情報を取得しようとしているように見えます。iasync
research
これは次のように行うのが最適ですpgrep
:
pgrep -l -U research 'rsync|iasync'
これらのプロセスにシグナルを送信するには、pkill
の代わりにを使用しpgrep
、-l
オプションを削除します。
完全なスクリプトは次のようになります。
#!/bin/sh
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
printf 'Processing host "%s"\n' "$remote"
ssh "$remote" 'pgrep -l -U research "rsync|iasync"'
done
または、以下を使用しますxargs
:
#!/bin/sh
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
xargs -I {} sh -c '
printf "Processing host \"%s\"\n" "$1"
ssh "$1" "pgrep -l -U research \"rsync|iasync\""' sh {}
がサポートしている場合は、 を使用して一度にxargs
複数のプロセスを実行できます。ここで、は実行を継続する必要がある同時コマンドの数です。sh -c
-P n
n
sh -c
xargs
答え2
EOF bash 機能は、基本的に、例のように、複数行のテキストを別のコマンドに送信するために使用されます。
これをワンライナーにしたい場合、EOF を削除する必要があります。
ssh を使用してリモート ホスト上でコマンドを実行するには、次の手順に従います。
ssh host command
例えば:
ssh host "ls -alh"
ホスト上でコマンドを実行し、コンソールに出力を返します。
引用符の使い方に注意すれば、サンプル コードを次のように 1 行に書き直すことができます。
ssh host "ps -ef | egrep 'rsync|iasync' | awk -F' ' '{if (\$1 ~ \"research\") print \$2}'"
この二重引用符で囲まれた文字列は、個々のコマンドの引数を一重引用符で囲みます。さらに二重引用符が必要な場合 ( "research
" パターン) は、 でエスケープする必要があり\
、文字も同様にエスケープする必要があります$
。