I am attempting to clear out all existing services configured in firewalld via a bash script.
# 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}"
When this is run, firewall-cmd returns:
Warning: NOT_ENABLED: {cockpit,dhcpv6-client,ssh}
success
The problem seems to be firewall-cmd interprets the list of services to disable as a single service name, instead of a list. When I run the command manually from the shell, the same exact (copy/pasted) command works like expected.
Example script to replicate:
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}"
Results:
What is the difference between running this via script and via direct shell commands?
Update: Tried running the script with set -x as suggested by @fra-san, which produced the following results when run from the script:
And the following results when run from the shell:
It seems the shell (and/or firewalld) behaves differently when run interactively and expands the list of services into 3 separate --remove-service= flags. This is very unexpected behavior.


