in reply to Parsing command-line arguments in a sophisticated way.

Assuming the option-names to '--job' are not valid for your command line except as args to '--job', then I would use Getopt::Long with Getopt::Long::Configure("pass_through"); to parse what valid options it sees and ignore the rest, leaving them in ARGV. Then you either do a 2nd pass of options-parsing or pass ARGV straight to "job".

use strict; use warnings; use Getopt::Long; # ignore unknown options Getopt::Long::Configure("pass_through"); my ($afile, $adir); print "ARGV before: ".join(" ", @ARGV)."\n"; GetOptions( # do not add --job, do not add any options meant to be for --j +ob '--file=s' => \$afile, '--dir=s' => \$adir, ) or die "error in command line\n"; print "ARGV after: ".join(" ", @ARGV)."\n";
# execute: ./getopt_long.pl --dir d1 --job some-job -fw "hello" --file f1 ARGV before: --dir d1 --job some-job -fw hello --file f1 ARGV after: --job some-job -fw hello # notice how --file is after --job but still processed

But I think the "proper" way, if there is one, should be to bundle all arguments to "--job" in a string like --job '123 -fw "hello"' and parse options via Getopt::Long or similar. However, even in bash, it is a challenge to quote. Assuming users will always leave '--job' as last argument is not wise AFAIC.