Jun 11

Running a java program from your shell script is commonplace for Batch operations.  And the wrapper shell script doesnt know about the success/failure of the wrapped Java program unless we return an exit code. 

In most cases, we have the Java source on hand. For others who use a different mechanism to achieve the functionality of the batch operation, I am not sure how far this will be useful to you.

The only possible mechanism (at least that’s what i know) is to give out your exit code using the System.exit (int) method call.  I would suggest you to keep off status codes 0-255 because that is already reserved in Unix platforms (Solaris inclusive).

For the DOS, you use the ERRORLEVEL to catch your exit status.

echo %ERRORLEVEL% should give you a number indicating the exit code of your last executed program.

For bash and ksh, it is $?  as in “echo $?”

For cshell, it is $status as in “echo $status” which returns.  I dont see $? working on cshell (at least on my Solaris box).

When you are calling a Java program from inside a Java program (using Runtime.exec()), the code will look something like this (more elegant, of course) :

Assume the following program is the one which is called

public class WaitAndTerminate {
public static void main(String[] args) {
System.out.println(”Program begin”);
System.exit(1000);
System.out.println(”Program exit”);
}
}

and this is your caller program

 
public class Caller {
public static void main(String[] args) {
BufferedReader inStream=null;
try {
System.out.println(”Caller start”);
Process process=Runtime.getRuntime().exec(”java WaitAndTerminate”);
inStream = new BufferedReader(new InputStreamReader( process.getInputStream() ));
//the waitFor waits for the called program to exit
process.waitFor();
System.out.println(process.exitValue());
} catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException ie){
ie.printStackTrace();
}
}
}

The getInputStream() method of the Process, as you can see, grabs the output of the called program so that it could be logged.

One other main utility of this mechanism is that we can get to know whether the Java program succeeds completely or not.  In which case, make the last line of your main program return a System.exit(1000) (which indicates that the program is terminated successfully). Any termination in the middle (assuming a system restart or assuming that the called program is a webservice client making a call to a service hosted on a application server which is restarting - My God) will not return a status code of 1000. Ideally, it would return 2 or something like that.

Lets code that into Java now with a bit of modification into our previously written code.


public class WaitAndTerminate {
public static void main(String[] args) {
System.out.println(”Program begin”);
Object object=new Object();
synchronized (object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(1000);
System.out.println(”Program exit”);
}
}

The Caller Program is this :
 The destroy() method forcefully terminates the application, giving out a status code of 1.

public class Caller {
public static void main(String[] args) {
BufferedReader inStream=null;
try {
System.out.println(”Caller start”);
Process process=Runtime.getRuntime().exec(”java WaitAndTerminate”);
inStream = new BufferedReader(new InputStreamReader( process.getInputStream() ));
System.out.println(inStream.readLine());
//forceful termination of the called program
process.destroy();
process.waitFor();
System.out.println(process.exitValue());
} catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException ie){
ie.printStackTrace();
}
}
}

Output :
Caller start
Program begin
1

Tags: , ,

Mar 02

The find command in Unix always goes recursive. In order to avoid recursion into subfolders, you have the find -maxdepth in certain flavours of Unix. But find -prune is the standard way to restrict recursion into certain subfolders.

Consider you have a logs folder /apps/myapp/data/logs and a subfolder /apps/myapp/data/logs/history, you would like to move the files in the logs folder alone and NOT the files in the history folder, then issue

find * \( ! -name history -prune \) -type f - exec cp {} /apps/myapp/archive \;

keeping the pwd as /apps/myapp/data/logs.

If you wish to restrict more than one folder, then use

find * \( ! -name history -prune \) -o \( ! -name history -prune \) -type f - exec cp
{} /apps/myapp/archive \;

“-o” just says “OR”

Tags:

Mar 02

It common to get a huge backlog of log files in any application. Worse is the case when the application has a batch interface too.  And there comes the need to delete the files which are older comes up. Or you might want to just copy/move the files to an archive folder for later reference.

Here are the unix commands for them :

Copy to archive folder

Consier your log folder is /apps/myapp/data/logs and your archive folder is /apps/myapp/archive/logs and you want to copy “files” and not directories which are 5 days old , then

find /apps/myapp/data/logs -type f -mtime +5 -name '*.log' - exec cp {} /apps/myapp/archive/logs \;

and/or if you want to delete the files which are 5 days old,

find /apps/myapp/data/logs -type f -mtime +5 -name '*.log' - exec rm -f {} \;

Feb 10

We just love to have that single page “quick reference” posters on our cabin. Isn’t it?

CheatsheetsCheatsheets

Download lots and lots of cheatsheets of whatever technology you like. Here are the URLs

http://www.fuzzyopinions.com/

http://whatis.techtarget.com

Tags: , ,

Feb 03

Everybody handling a Unix operating system would very well know what chmod 777 means. That the owner, group and the user of the file is given all permissions (Read, Write and Execute on a particular file). This could otherwise be written as “chmod ugo+rwx “. Meaning that you are giving User, Group and Owner of the file, the rights to Read, Write and Execute the file.

Here comes the rws scenario. Best example that is available for this rws is /usr/bin/passwd command (just issue a “ls -l /usr/bin/passwd”) .

Normally, any user is allowed change HIS password. Meaning he can make an entry or change HIS entry in the /etc/passwd file. But he can never be given ‘WRITE’ permissions on the file because he might end up disturbing other person’s password too. Only a ROOT user is allowed permissions on the /etc/passwd file.

This is where the “rws” comes to picture. When we give “rws” permission to the /usr/bin/passwd command, Unix would assume that the command is executed by the ROOT user. (the user doesnt have permissions on the /etc/passwd file but the root user has). Root user (RWS) permissions could be given on a file as chmod 4700 .

arun@arun-desktop:~/Desktop$ chmod 4700 hi.txt
arun@arun-desktop:~/Desktop$ ls -l hi.txt
-rws—— 1 arun arun 0 2007-01-17 06:48 hi.txt

If you need to act as a group user of a file and not a normal user when executing a particular command (as against the root user) then user “chmod 2700 ”

arun@arun-desktop:~/Desktop$ chmod 2700 hi.txt
arun@arun-desktop:~/Desktop$ ls -l hi.txt
-rwx–S— 1 arun arun 0 2007-01-17 06:48 hi.txt

The 4 and 2 in the front of the chmod commands are called as SUID and SGID bits.

What if we put a 1 instead of 4 and 2 (chmod 1700 ).

arun@arun-desktop:~/Desktop$ chmod 1700 hi.txt
arun@arun-desktop:~/Desktop$ ls -l hi.txt
-rwx—–T 1 arun arun 0 2007-01-17 06:48 hi.txt

It shows a “T” in the place of “x” for a normal user. This “T” bit is called as the Sticky bit.

“When the sticky bit is turned on for a directory users can have read and/or write permissions for that directory, but they can only remove or rename files that they own. The sticky bit on a file tells the operating system that the file will be executed frequently. Files like this are kept in swap space even when they aren’t being executed. Although this takes up swap space it greatly reduces the time it takes to execute the program. Some programs such as vi have the sticky bit turned on by default on some Unixes.”

source : http://www.uwsg.iu.edu

Tags: ,

Give your best to the world.