ワンライナーでヒアドキュメントを使用しますか?

ワンライナーでヒアドキュメントを使用しますか?

sshhere-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ここでは、 ++コマンドawkgrep1 つのコマンドに結合しました。また、ホスト名を中間変数に格納するのではなく、コマンドでループに直接入力するようawkにしました。awk

ループ内では、ユーザーに属するrsyncまたはプロセスに関する情報を取得しようとしているように見えます。iasyncresearch

これは次のように行うのが最適です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 nnsh -cxargs

答え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" パターン) は、 でエスケープする必要があり\、文字も同様にエスケープする必要があります$

関連情報