1. #!/usr/bin/perl 2. 3. use strict; 4. use warnings; 5. 6. # pathcompare.pl compares the PATH across hosts names 7. # pathcompare.pl -host host1 -host host2 -host host3 .. 8. # 9. # optional specify the PATH: -path 'colon-delimited-path' 10. # optional specify what to view: -view comp2sets,sim 11. # 12. # Example: 13. # pathcompare.pl -host mm01 -host vienna -view comp2sets,sim 14. 15. usage() unless @ARGV > 1; 16. sub usage { print join "",<DATA>; exit; } 17. 18. #my $PATH = "/opt/ASPLv1.00/bin:/opt/ASPLv1.00/shared"; 19. my $PATH = ""; 20. my @hosts; 21. my $view = "sim"; 22. my $dbg = 0; 23. 24. 25. while (@ARGV) { 26. if ($ARGV[0] eq '-path') { 27. shift @ARGV; 28. $PATH = shift; 29. } 30. elsif ($ARGV[0] eq '-host') { 31. shift @ARGV; 32. my $host = shift; 33. push(@hosts,$host); 34. } 35. elsif ($ARGV[0] eq '-view') { 36. shift @ARGV; 37. $view = shift; 38. } 39. elsif ($ARGV[0] eq '-dbg') { 40. shift @ARGV; 41. $dbg = 1; 42. } 43. elsif ($ARGV[0] eq '-help') { 44. usage(); 45. } 46. else { 47. die "UNKNOWN OPTION $ARGV[0]\n\n"; 48. } 49. } 50. 51. usage() unless @hosts >=2; 52. if (length $PATH) { $PATH = ",PATH,$PATH"; } 53. 54. my $interpreter = "aspl -groupingclass POSIX -wsname TRANSIENT -singlepass -dm 3"; 55. 56. # NOTE shebang arguments take priority over interpreter preceding -STDIN 57. #my $shebang = "#!/opt/ASPLv1.00/bin/aspl -groupingclass POSIX -wsname TRANSIENT -singlepass -dm 1"; 58. my $shebang = ""; 59. my $s = "$shebang\n"; 60. 61. $s .= q~DEF FN cmp2sets := {gU {g\, %%1 %%2}{g\, %%2 %%1}{g&, %%1 %%2}}~ . "\n"; 62. $s .= "timeout 300\n"; 63. $s .= "displayoff\n"; 64. 65. # The host name can be used as the symbol of the ASPL set variable, and it can also 66. # be used as the label name of the ASPL ser variable. 67. # We will create ASPL variables using the host names and labeling their grp1 with 68. # the same. 69. 70. foreach my $host (@hosts) { 71. if ($host =~ /^localhost$/i) { 72. $s .= "$host = ggpath(grp1,$host $PATH)\n"; 73. } 74. else { 75. # remote hostname call ggpathR() 76. $s .= "$host = ggpathR(grp1,$host,hostname,$host $PATH)\n"; 77. } 78. } 79. my @hosts2 = @hosts; 80. my $t = $hosts2[0]; 81. $hosts2[0] = $hosts2[1]; 82. $hosts2[1] = $t; 83. 84. # views table 85. my $ascmd = ""; 86. foreach (split(/\s*\,\s*/,$view)) { 87. ($_ =~ /^union$/i) && ($ascmd .= "gU @hosts\n") || 88. ($_ =~ /^funion$/i) && ($ascmd .= "fU @hosts\n") || 89. ($_ =~ /^dunion$/i) && ($ascmd .= "dU @hosts\n") || 90. ($_ =~ /^inter$/i) && ($ascmd .= "g& @hosts\n") || 91. ($_ =~ /^finter$/i) && ($ascmd .= "f& @hosts\n") || 92. ($_ =~ /^dinter$/i) && ($ascmd .= "d& @hosts\n") || 93. ($_ =~ /^finterc$/i) && ($ascmd .= "f&`c= @hosts\n") || 94. ($_ =~ /^finterc~$/i) && ($ascmd .= "f&`c~ @hosts\n") || 95. ($_ =~ /^fdiff$/i) && ($ascmd .= "f\\ @hosts\n") || 96. ($_ =~ /^fdiff2$/i) && ($ascmd .= "f\\ @hosts2\n") || 97. ($_ =~ /^sdiff$/i) && ($ascmd .= "gD @hosts\n") || 98. ($_ =~ /^useq$/i) && ($ascmd .= "f%U @hosts\n") || 99. ($_ =~ /^iseq$/i) && ($ascmd .= "f%& @hosts\n") || 100. ($_ =~ /^sim$/i) && ($ascmd .= "sim @hosts\n") || 101. ($_ =~ /^simc$/i) && ($ascmd .= "sim`fflc @hosts\n") || 102. ($_ =~ /^simz$/i) && ($ascmd .= "sim`fflz @hosts\n") || 103. ($_ =~ /^comp2sets$/i) && ($ascmd .= "FN cmp2sets($hosts[0],$hosts[1])\n") || 104. die "\n UNKNOWN VIEW SPECIFIER $_\n\n"; 105. } 106. 107. $s .= "displayon\n"; 108. $s .= $ascmd; 109. $s .= "v\n"; 110. 111. if ($dbg) { print "$s\n\n"; exit; } 112. 113. open(ASPL, "| $interpreter -STDIN") or die "ERROR OPENING A PIPE TO aspl: $! \n"; 114. print ASPL $s; 115. close ASPL; 116. 117. __END__ 118. 119. Use ASPL run time interpreter to compare the PATH across machines in a cloud environment. 120. 121. pathcompare.pl [-path PATHSTRING] [-view VIEWSPEC] -host host1 -host host2 .. -host hostN 122. 123. specifying path is optional and if not specified then use the PATH from env 124. asis being set on the UNIX host for the user running this script. 125. 126. specifying the SPECS is optional, and it is formed of a comma delimited 127. string of the following keywords: 128. union displays the union of directories and files 129. funion displays the union of files 130. dunion displays the union of directories and subdirectories 131. inter displays the intersection directories and subdirectories 132. finter displays the intersection of files 133. dinter displays the intersection of directories and subdirectories 134. finterc displays the intersection where checksums are the same 135. finterc~ displays the intersection where checksums are different 136. fdiff displays the difference between 137. fdiff2 displays the difference between 2nd host and the 1st 138. sdiff displays the symmetric difference 139. useq displays the sequence alignment of the union 140. iseq displays the sequence alignment of the intersection 141. sim displays the similarity 142. simc displays the similarity for files with same checksum 143. simz displays the similarity for files with same ks 144. cmp2sets displays comparison of only the first two hosts 145. 146. You can specify any of the SPECS in any order, and that is the order 147. they will be displayed when the command terminate. 148. When -view is not specified, then default to display the similarity. 149. 150. At least two host names must be specified. If localhost is used 151. then the PATH of the current host is gathered, and any other host name 152. is treated as a remote host. The remote hosts must be ssh configured 153. and ssh'able from the machine where this script is executed 154. otherwise the script will fail to gather the PATH of the remote host. 155. 156. For sequence alignment only the two hosts are subject to alignment, and 157. specifying three hosts will mediate the alignment (see ASPL documentation). 158. 159. -dbg shows the ASPL code without executing it 160. 161. Example: 162. pathcompare.pl -path '/usr/lib64:/usr/sbin' -host localhost -host mm02 -host mm03 163. pathcompare.pl -path '/usr/lib64:/usr/sbin' -host localhost -host vienna -view iseq,sim 164. pathcompare.pl -host localhost -host vienna -view sim 165.