awk間の配管を避ける方法は?

awk間の配管を避ける方法は?

私は私のユーザーから実行される次のスクリプトを書いてcrontabSSHポート転送を解析し、行が~/.ssh/config「リモート」、「ローカル」、または「動的」で終わると自動的に接続します。Host

ブロック例~/.ssh/config

Host localsocksdynamic
     DynamicForward 8080
     Hostname 1.2.3.4

Host localwebserverremote
     RemoteForward *:8080 localhost:80
     Hostname 1.2.3.4

Host indirectaccesslocal
     LocalForward 2222 2.3.4.5:80
     Hostname 1.2.3.4

スクリプト:

#!/bin/sh

port_forwards=$(awk '/Host .*(remote|local|dynamic)/{printf $2} " "}' ~/.ssh/config  
for forward in ${port_forwards}
do
     port=$(awk "/${forward}/{f=1;next}/Host /{f=0}f" ~/.ssh/config | awk '/(Remote|Local|Dynamic)Forward/{print $2}' | cut -d':' -f2)
     [ -z ${port} ] || nc -z 127.0.0.1 ${port} || ssh -fqN ${forward} > /dev/null 2>&1
done

うまく動作しますが、あるコマンドを別のコマンドにパイプする必要がないように、コマンドを1行にまとめることがawkできるかどうか疑問に思います。何時間も構文を理解しようとしましたが、理解できませんでした。port=awk

私はautossh私がやっていることを行うより良い方法があることを知っていますが、これは学習経験であり、パッケージをインストールせずに同じことをしようとしています。

ベストアンサー1

単一のAWK呼び出しで任意のテキスト処理を実行できます。これは配信にのみ興味があるので簡単です。

#!/bin/sh

awk '/^Host / { host = $2 } host && /(Remote|Local|Dynamic)Forward/ { port=$2; gsub(".*:", "", port); print host, port }' ~/.ssh/config | while read host port; do
    nc -z 127.0.0.1 "${port}" || ssh -fqN "${host}" > /dev/null 2>&1
done

AWKスクリプトはより明確に書かれています。

/^Host / { host = $2 }

host && /(Remote|Local|Dynamic)Forward/ {
    port=$2; gsub(".*:", "", port); print host, port
}

「Host」ステートメントを表示するたびにホストを保存し、有効なホストを定義し、許可された「Forward」ステートメントの1つと一致するときに出会う行からコロンの前の部分を削除してターゲットポートを検索します(存在する場合)。 )、ホストとポートを出力します。

localsocksdynamic 8080
localwebserverremote 8080
indirectaccesslocal 2222

while read次に、ループに入れてポートを確認し、SSHを実行します。

おすすめ記事