I'm writing some iptables scripts, and I want to write a function that takes an arbitrary number of parameters and consumes them two at a time. Here's an example:

# Allow inbound sessions for a specific service
iptables --append INPUT --protocol $PROTO --destination-port $PORT \
   --match state --state NEW --jump ACCEPT || exit 1

I found this thread that shows the right syntax for looping through an arbitrary number of arguments, but I don't know how to grab two arguments in each iteration. How do I get both $PROTO and $PORT from the caller (from $@, two args at a time)?

  • I don't quite understand what you're asking. Where do $PROTO and $PORT come from? Where's your arbitrary number of parameters? What is an example of how you'd like this script to be called?
    – Celada
    Feb 22, 2017 at 20:53

1 Answer 1


You could do:

#! /bin/sh -
while [ "$#" -ge 2 ]; do
  proto=$1 port=$2
  shift 2
  iptables --append INPUT --protocol "$proto" --destination-port "$port" \
    --match state --state NEW --jump ACCEPT || exit 1

With zsh:

#! /bin/zsh -
for proto port do
  iptables --append INPUT --protocol "$proto" --destination-port "$port" \
    --match state --state NEW --jump ACCEPT || exit 1

One difference is that if there's an odd number of argument, there will be an extra run with $proto containing the last argument and $port being set but empty (as if we had used [ "$#" -gt 0 ] instead of [ "$#" -ge 2 ] in the previous example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.