Search code examples
javawindowscygwincommand-promptterminal-emulator

Quickly find if Java was launched from Windows cmd or Cygwin terminal


I have a Java application that will be used both from the Windows Command Prompt and the Cygwin terminal. The program uses and manipulates file paths. It we be very useful to have a sep variable that would be / when the program is launched from Cygwin but \\ when the program is launched from Windows.

Looking here, I'm not sure it will be possible, but I want to ask.

I will post a small, compilable app that shows the issue in a few minutes. For now, I'll just say that I want a set of functions that something like:

// in main
...
String sep = getSeparatorToUse();
...

// member functions
...
private boolean wasLaunchedFromWinCmd() 
{
  if (<something-here-that-knows-it-was-cmd-not-cygwin>)
    return true;

  return false;

}//endof:  private boolean wasLaunchedFromWinCmd()

private String getSeparatorToUse()
{
  if (wasLaunchedFromWinCmd)
    return "\\"

  return "/"

}//endof:  private String getSeparatorToUse()

Thanks @Raphael_Moita. Those are very useful, and I will likely use them in the Linux version of the app that I will be using. @Luke_Lee, I feel dumb not having realized it. I think you two might have solved my problem while I was getting the compilable code ready. There's still one issue when the program run from a batch script - when it is fed a filename from a find command. I hope what I show will illustrate that.

Examples

All examples are as run from Cygwin.

Works: the way most volunteers use the code, just the filename that's in the same directory as the java code.

$ java FileSeparatorExample pic_4.jpg
Here, something will be done with the file,
C:\Users\bballdave025\Desktop\pic_4.jpg

Works: with relative filepaths and spaces in filenames/file paths

$ java FileSeparatorExample pretty\ pictures/pic\ 1.jpg
Here, something will be done with the file,
C:\Users\me\Desktop\pretty pictures/pic 1.jpg

$ java FileSeparatorExample ../pic_5.jpg
Here, something will be done with the file,
C:\Users\me\Desktop\../pic_5.jpg

DOESN'T WORK. Sometimes, the output of a find command will come with the complete filepath in Cygwin/UNIX format:

$ java FileSeparatorExample /cygdrive/c/David/example/pic.jpg
The file:
C:\Users\bballdave025\Desktop\/cygdrive/c/David/example/pic.jpg
doesn't exist

Compilable Code

I'm just cutting down from my original code, so I'm sorry if it seems too big.

/**********************************
 * @file FileSeparatorExample.java
 **********************************/

// Import statements
import java.io.File;
import java.io.IOException; 

public class FileSeparatorExample
{ 
  // Member variables
  private static String sep;


  public static void main(String[] args) 
  {
    ////****** DOESN'T WORK AS DESIRED ******////
    sep = java.io.File.separator;
    ////** I want **////
    // sep = getFileSeparator();

    String imageToLoad = null;
    boolean argumentExists = ( args != null && args.length != 0 );

    if (argumentExists)
    {
      boolean thereIsExactlyOneArgument = ( args.length == 1 );
      if (thereIsExactlyOneArgument)
      {
        imageToLoad = args[0];
      }//endof:  if (thereIsExactlyOneArgument)
      else
      {
        // do some other stuff
      }

    }//endof:  if (argumentExists)

    String filenamePath = getFilenamePath(imageToLoad);
    String filenameFile = getFilenameFile(imageToLoad);

    imageToLoad = filenamePath + sep + filenameFile;

    File f = new File(imageToLoad);
    if (! f.exists())
    {
      System.err.println("The file:");
      System.err.println(imageToLoad);
      System.err.println("doesn\'t exist");  

      System.exit(1);

    }//endof:  if (! f.exists())

    System.out.println("Here, something will be done with the file,");
    System.out.println(imageToLoad);

  }//endof:  main


  // member methods
  /**
   * Separates the filename arg into: full path to directory; bare filename
   */
  private static String[] splitFilename(String imageToLoad)
  {
    String[] fileParts = new String[2];

    int indexOfLastSep = imageToLoad.lastIndexOf(sep);
    boolean fullFilenameHasSeparator = ( indexOfLastSep != -1 );
    if (fullFilenameHasSeparator)
    {
      fileParts[0] = imageToLoad.substring(0, indexOfLastSep);
      fileParts[1] = imageToLoad.substring(indexOfLastSep + 1);

    }//endof:  if (fullFilenameHasSeparator)
    else
    {
      // Use the user's directory as the path
      fileParts[0] = System.getProperty("user.dir");
      fileParts[1] = imageToLoad;

    }//endof:  if/else (fullFilenameHasSeparator)

    return fileParts;

  }//endof:  private static String[] splitFilename(String imageToLoad)

  /**
   * Gives the full path to the file's directory (from the filename arg)                       
   * but not the bare filename
   */
  private static String getFilenamePath(String imageToLoad)
  {
    String[] fileParts = splitFilename(imageToLoad);
    return fileParts[0];

  }//endof:  private static String getFilenamePath(String imageToLoad)


  /**
   * Gives the bare filename (no path information)
   */
  private static String getFilenameFile(String imageToLoad)
  {
    String[] fileParts = splitFilename(imageToLoad);
    return fileParts[1];

  }//endof:  private static String getFilenamePath(String imageToLoad)

}//endof:  public class FileSeparatorExample

Solution

  • You don't need to know which SO is under your Java. If your goal is to find the correct file separator to use, call this:

    java.io.File.separator;
    

    Anyway ... to find out which SO java is running over (not sure how cygwin is detected by this), try:

    boolean isWindows = System.getProperty("os.name").startsWith("win");