Tag Archives: cygwin

Using Powershell instead of cygwin for scripting

In this blog entry, Windows Tricks For Whacking Lingering Java Processes …, the author resorts to the cygwin linux shell to automate an admin need.  Now cygwin is awesome, bringing some of the best tools from *nix.  However, with Powershell, Microsoft finally transformed the Windows command line into a powerful and usable administration resource.

Below a line from the bash script the author used to find each process given a process name and then loop thru each process ID and terminate it.   Note how the script requires a good understanding of bash scripting and in addition multiple Linux utilities  ps, grep, and sed.   The most important line in the script is:

found=` ps -aW | grep $procText |  sed -e's/^s*([0-9][0-9]*).*/1/' `
Here is how this works.
ps -aW:   show all processes and windows too.
grep $procText:   only use lines that contain the command line string
sed -e:   run stream editor inline
s///:   substitute
^s*:  all beginning white space
([0-9][0-9]*):  find two or more digits, remember these.
.*:  any characters.
/1/:  replace with the found digits

Very complex!!!! But, to *nix users this is nothing. Its even fun to do. With a Linux command line you can rule the world. Note that in the above script line, it’s just text processing.

Powershell has a different approach. In Powershell one works with objects (in the OOP sense). Thus, instead of transforming everything to text, one manipulates properties of objects. One pipes object instead of text.

To do:
Show how to do this in Powershell. Unfortunately, wrote the above a long time ago and lost what little Powershell mojo I was developing. Any help?

Update
3/18/12: The powershell approach will probably be expanded from something like this, which just lists the processes by name and process ID:

$strComputer = "."

$colItems = get-wmiobject -class "Win32_Process" -namespace "rootCIMV2" `
-computername $strComputer

foreach ($objItem in $colItems) {
      write-host "Name: " $objItem.Name
      write-host "Process ID: " $objItem.ProcessId
}

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Use SED or Groovy to print paths, split with line feeds

Yea, this is easy, IF you use SED much. Now I updated this post with a Groovy approach, since this is easier to install where cygwin may be prohibited.

Using SED
With cygwin installed, SED, the stream editor is available. In a command shell, execute:

set path | sed s_;_;\n_g

Update: fixed the sed above, was missing the backslash before the n.

Explanation

  1. set path will print the Windows path. File path entries are separated by “;”.
  2. sed will invoke the cygwin installed linux SED command. Cygwin\bin is part of the executable path.
  3. “s” indicates the substitute command
  4. “_”, the underscore is used as the delimiter to each part of the substitution. One can use other characters for the delimiter.
  5. “;” is the regular expression to use for a match.
  6. “;\n” is the string to substitute with. \n is the crlf.
  7. “g” is the substitute flag, global replacement

No doubt there are more direct ways of doing this. Using PowerShell would be the most appropriate on Windows if it is available.

Using Groovy
Another approach is using the Groovy language, which has a command line mode using the “-e” switch:

set path | groovy -e "System.in.text.split(';').each{ println it}"

Explanation
The output of set path is piped to an inline Groovy script. The script uses the “text” value of the System.in standard input stream. ‘text’ is some magic Groovy dust. The Groovy development kit (GDK) extends Java io streams with a method, textO(), that gets the string value of the stream, like read a file. This is available as a java bean getter method, which again via magic is available as a field, “.text”. The string is then split, then a closure “each” is used to print each line, passed to the closure with the default variable “it”.

Example
If your path is: C:\fee;d:\fi;c:\foo;fum

The result would be:
C:\fee;
d:\fi;
c:\foo;
fum

You can, of course, pipe these together to allow finer control. However, the high level language makes for very long winded code, for example, find all properties in Java system properties that have the word ‘Java’ or ‘java’:

groovy -e "System.properties.each{println it}" | groovy -e "System.in.eachLine{ if(it.find('[jJ]ava')) println it}"

Better would be, just putting the filtering inside the closure:

groovy -e "System.properties.each{ if(it.key.find('[jJ]ava')) println it}"

Or as a script:

System.properties.each{ 
     if(it.key.find('[jJ]ava')){ 
        println it
     }
}

Consult the Groovy documentation for further Groovy syntax and idioms to make the above even better.

References

  1. GNU sed
  2. Sed – An Introduction and Tutorial by Bruce Barnett
  3. SED, stream editor
  4. PLEAC-Groovy
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.