Sun Solaris


Finding files by specifying their modification time

The find command is one of the most flexible and powerful commands in the Solaris operating system. You can use it to find files with almost any search criteria and then perform operations on the files it finds. As an example, suppose you created a file in the /home/fred directory within the last 30 days, but you can't remember the name of the file. To search for all files that were modified in the /home/fred directory within the last 30 days, use the following command:


$  find /home/fred -mtime -30 -print

Suppose, however, that you created the file more than 30 days ago. To search for files in this directory modified more than 30 days ago, simply change the -30 to +30:


$  find /home/fred -mtime +30 -print

Finally, if you somehow knew that you modified the file exactly 30 days ago, exclude the sign on the number 30 altogether to search for files modified exactly 30 days ago:


$  find /home/fred -mtime 30 -print


Keep commands running after you leave with nohup

It's 3 p.m., and you want to start a long job running. Unfortunately, you can't be sure that the job will finish by 5 p.m. when you need to leave, and the company is very strict about making sure you log off when you leave. However, if you log off the system, the job will be stopped. What can you do?

On Solaris systems you can use the "nohup" (no hang-up) command to keep jobs running long after you log off the system. Using nohup tells the system not to "hang-up" on your job after you've logged off the system.

Here's how to run the job, and keep it running after you log off:


root>  nohup my-long-job &

This creates a file named "nohup.out" in the current directory that contains the standard output of the command ("my-long-job") you're running. Everyone is happy because the job keeps running, you get to leave at 5 p.m., and you're properly logged off the system.


Use rsh to run commands on somebody else's computer

Here's a hypothetical situation for you: On the "Sesame Street Network", you're logged into a Solaris workstation named "elmo", and you need to look at the man pages for the tar command. Unfortunately the man pages aren't installed on this workstation.

If you're on a network of Solaris computers like this, and you know that the man pages are installed on another workstation named "bigbird", the solution is simple. Simply run the man command on bigbird, like this:


elmo>  rsh bigbird "man ksh" | more

This runs the "man ksh" command on bigbird, and pipes the output of the command into the "more" command on elmo.

Here's a few other "rsh" commands you can run on remote workstations:


rsh bigbird "who"
rsh ernie "ps -ef"
rsh grover "ls -al /home"


Use CDPATH to traverse filesystems faster

If you're like many Solaris users and administrators, you spend a lot of time moving back and forth between directories in similar locations. For instance, you might often work in your home directory (such as "/home/al"), the /usr/local directories, web page directories, or other user's home directories in /home.

If you're often moving back-and-forth between the same directories, and you use the Bourne shell (sh) or Korn shell (ksh) as your login shell, you can use the CDPATH shell variable to save yourself a lot of typing, and quickly move between directories.

Here's a quick demo. First move to the root directory:


	cd /

Next, if it's not set already, set your CDPATH shell variable as follows:


CDPATH=/usr/spool

Then, type this cd command:


	cd cron

What happens? Type this and see what happened:


	pwd

The result should be "/usr/spool/cron".

When you typed "cd cron", the shell looked in your local directory for a sub-directory named "cron". When it didn't find one, it searched the CDPATH variable, and looked for a "cron" sub-directory. When it found a sub-directory named cron in the /usr/spool directory, it moved you there.

You can set your CDPATH variable just like your normal PATH variable:


	CDPATH=/home/al:/usr/local:/usr/spool:/home


Group commands together with parentheses

Have you ever needed to run a series of commands, and pipe the output of all of those commands into yet another command?

For instance, what if you wanted to run the "sar", "date", "who", and "ps -ef" commands, and wanted to pipe the output of all three of those commands into the "more" command? If you tried this:


	sar -u 1 5; date; who; ps -ef | more

you'll quickly find that it won't work. Only the output of the "ps -ef" command gets piped through the "more" command, and the rest of the output scrolls off the screen.

Instead, group the commands together with a pair of parentheses (and throw in a few echo statements for readability) to get the output of all these commands to pipe into the more command:


	(sar -u 1 5; echo; who; echo; ps -ef; echo; date; echo) | more


A shell function to get one character at a time from the end user

Many times people writing shell programs want to prompt an end-user to "Hit Any Key to Continue" during the middle of a shell program. However, they often settle for lesser functionality, because they think it's not easy to get one keystroke at a time from the end user.

The "GetKeystroke" function shown below shows exactly how to get one character at a time from your end-users in your Bourne shell/Korn shell programs:


-----------------------------------------------------------------
#!/bin/sh                                       
                                                
GetKeystroke () {                               
   trap ""  2 3                                 
   oldSttySettings=`stty -g`                    
   stty -echo raw                               
   echo "`dd count=1 2> /dev/null`"             
   stty $oldSttySettings                        
   trap  2 3                                    
}                                               
                                                
                                                
#----------------------------------------------#
#  Here's the main program.  Hit "x" to exit.  #
#----------------------------------------------#
                                                
keyStroke=""                                    
while [ "$keyStroke" != "x" ]                   
do                                              
   clear                                        
   echo "HIT ANY KEY TO CONTINUE: \c"           
   keyStroke=`GetKeystroke`                     
done

-----------------------------------------------------------------

To test this program, try the following:


1. Save the code between the lines in a file named /tmp/keytest
2. Make the program executable:
      chmod +x /tmp/keytest
3. Run the program:
      /tmp/keytest

You'll see that you can hit one character at a time, without the need to hit the [Enter] key.  When you're finished testing, type "x" to leave the program.


Finding text strings in binary files

Ever wondered what's inside some of those binary files on your system (binary executables or binary data)? Several times I've gotten error messages from some command in the Solaris system, but I couldn't tell where the error was coming from because it was buried in some binary executable file.

The Solaris "strings" command lets you look at the ASCII text buried inside of executable files, and can often help you troubleshoot problems. For instance, one time I was seeing error messages like this when a user was trying to log in:


	Could not set ULIMIT

I finally traced the problem down to the /bin/login command by running the "strings" command like this:


	root>  strings /bin/login | more

The strings command lists ASCII character sequences in binary files, and help me determine that the "Could not set ULIMIT" error was coming from this file. Once I determined that the error message I was seeing was coming from this file, solving the problem became a simple matter.