
firewalld
Bashスクリプトを介して設定されたすべての既存のサービスを消去しようとしています。
# produces {cockpit,dhcpv6-client,ssh} as an example
local EXISTING_SERVICES="{$(firewall-cmd --permanent --list-service | sed -e 's/ /,/g')}"
# firewall-cmd --permanent --remove-service={cockpit,dhcpv6-client,ssh}
firewall-cmd --permanent --remove-service="${EXISTING_SERVICES}"
実行時にfirewall-cmd
以下を返します。
Warning: NOT_ENABLED: {cockpit,dhcpv6-client,ssh}
success
firewall-cmd
問題は、無効にするサービスのリストがリストではなく単一のサービス名として解釈されることです。シェルで手動で実行すると、まったく同じ(コピー/貼り付け)コマンドが期待どおりに機能します。
コピーするスクリプトの例:
EXISTING_SERVICES="{$(firewall-cmd --permanent --list-service | sed -e 's/ /,/g')}"
echo "firewall-cmd --permanent --remove-service=${EXISTING_SERVICES}"
firewall-cmd --permanent --remove-service="${EXISTING_SERVICES}"
結果:
スクリプトで実行することと、直接シェルコマンドで実行することの違いは何ですか?
更新:@fra-sanが提案したようにスクリプトを実行しようとしましたが、set -x
スクリプトで実行すると次の結果が表示されます。
シェルで実行したときの結果は次のとおりです。
インタラクティブに実行すると、シェル(および/またはファイアウォール)が異なる動作をするように見え、サービスリストを3つの別々のフラグ--remove-service=
に展開します。これは非常に予期しない動作です。
答え1
firewall-cmd
この点に関して、スクリプトでコマンドを実行することと対話的に実行することには違いはありません。代わりに、基本的に他の2つのコマンドを実行しています。
行動で見るものは支柱の拡張:注文する
firewall-cmd --permanent --remove-service={cockpit,dhcpv6-client,ssh}
Bashによって拡張
firewall-cmd --permanent --remove-service=cockpit --remove-service=dhcpv6-client --remove-service=ssh
これはスクリプトとコマンドラインの両方で発生します。ただし、シェルは追加の拡張トリガー文字を検索するために拡張結果を解析しません。したがって、コマンドは
firewall-cmd --permanent --remove-service="${EXISTING_SERVICES}"
スクリプトから次に展開します。
firewall-cmd --permanent --remove-service={cockpit,dhcpv6-client,ssh}
そしてその形式で動作します(中括弧内の式はこの時点で文字通り受け入れられます)。
これは有効なコマンドではないようですfirewall-cmd
。引用するman firewall-cmd
、構文は次--remove-service
のとおりです。
... --remove-service=service
サービスを削除します。このオプションは複数回指定できます。
一度に複数のサービスを削除するための推奨される方法は次のとおりです。
firewall-cmd ... --remove-service=foo --remove-service=bar ...
Bashを使用すると、配列を使用してアクティブなサービスを保存し、それらを削除するための適切なオプションのリストを作成できます。
services=( $(firewall-cmd --permanent --list-services) )
firewall-cmd --permanent "${services[@]/#/--remove-service=}"
${services[@]/#/--remove-service=}
Bashパラメータ拡張のパターン置換形式はどこにありますか?#
各配列要素の先頭にある空の文字列を一致させ、に置き換えます--remove-service=
。
あまり効率的ではありませんが、場合によってはiffirewall-cmd
のシャットダウン状態が変わるため、一度に1つのサービスを追加/削除する方が実用的かもしれません。0
少なくともどんなに多くのタスクが失敗しても、1つのタスクは成功します。その場合は、次のことを好むことができます。
services=( $(firewall-cmd --permanent --list-services) )
for serv in "${services[@]}"
do
firewall-cmd --permanent --remove-service="$serv" || echo "failed: $serv" >&2
done