Recently I had to extract a partial string from a space-seperated list of names in a loop within a script. There have to be two versions of that script, one for Windows and one for Linux shell. To loop through one such list is quite easy, in Windows:
@echo off SETLOCAL set WEBSITES=Test1 Test2 Test3 FOR /D %%A IN (%WEBSITES%) DO ( echo WebsiteName=%%A ) GOTO :EOF ENDLOCAL
and in Linux shell:
WEBSITES="Test1 Test2 Test3" for WEBSITE_ALIAS in $WEBSITES ; do echo "Website= $WEBSITE_ALIAS ..." done
But now came a second list of string into play containing the domain names of the website aliases:
WEBSITES="Test1 Test2 Test3" DOMAINNAMES="www.test1.lan www.test2.lan www.test3.lan"
In a conventional programming language I would just use a for-loop with an index variable and utilize that variable to access both arrays within one loop. But in that batch/shell scripting this turned out to be quite tricky. My solution here was a small inline PERL script. For Windows:
set WEBSITE_UNIT=Unit4 set WEBSITES=Test1 Test2 Test3 set DOMAINNAMES=www.test1.lan www.test2.lan www.test3.lan perl -e "use strict; die("argv mismatch!") if !@ARGV or scalar(@ARGV) < 2; my @Websites = split(/[s,;|]/, $ARGV[0]); my @Domains = split(/[s,;|]/, $ARGV[1]); die("number of aliases differs from domain names!") if scalar(@Websites) != scalar(@Domains); for(my $i=0; $i<scalar(@Websites); $i++) { system('perl dosomething.pl -user /Root/'.$ENV{'WEBSITE_UNIT'}.'/admin -passwd admin -servername '.$ENV{'SERVER_NAME'}.' -alias '.$Website[$i].''); system('perl doanotherthing.pl -user /Root/'.$ENV{'WEBSITE_UNIT'}.'/admin -passwd admin -alias '.$Website[$i].' DomainName="'.$Domains[$i].'"'); }" "%WEBSITES%" "%DOMAINNAMES%"
And for Linux:
WEBSITE_UNIT=Unit4 WEBSITES="Test1 Test2 Test3" DOMAINNAMES="www.test1.lan www.test2.lan www.test3.lan" perl -e 'use strict; die("argv mismatch!") if !@ARGV or scalar(@ARGV) < 2; my @Websites = split(/[s,;|]/, $ARGV[0]); my @Domains = split(/[s,;|]/, $ARGV[1]); die("number of aliases differs from domain names!") if scalar(@Websites) != scalar(@Domains); for(my $i=0; $i<scalar(@Websites); $i++) { system("perl dosomething.pl -user /Root/'${WEBSITE_UNIT}'/admin -passwd admin -servername ".$ENV{"SERVER_NAME"}." -alias ".$Website[$i].""); system("perl doanotherthing.pl -user /Root/'${WEBSITE_UNIT}'/admin -passwd admin -alias ".$Website[$i]." DomainName="".$Domains[$i]."""); }' "$WEBSITES" "$DOMAINNAMES"
Notice the different handling of the ticks and quotes and the different access to external parameters. In Windows there’s no difference in PERL’s $ENV hash whether accessing real environment variables or local variables set by the batch script. Not so under Linux: I can only access my system-wide exported environment variable SERVER_NAME using $ENV but not my local script’s WEBSITE_UNIT variable. When using the exec -e with perl for Windows I had to use quotes to wrap the execution PERL-code but for linux shell, I needed single ‘-ticks which can NOT be used inside the PERL code – not event when escapting them like ‘. The single ticks are “reserved” by the shell script for being able to insert shell variables anywhere.