Advanced Linux Commands
Advanced Linux Commands
 (useful for DBAs)
Last modified: December 2012
All Archives
by ShanNura
In this three-part series, you will learn some not-so-well-known tricks about various routine commands as well as variations in usage that make them more useful. As the series progresses, you will learn successively difficult commands to master.
Note: that these commands may differ based on the specific version of Linux you use or which specific kernel is compiled, but if so, probably only slightly.
Changes to Owner, Group, and Permissions
We already know how to use chown and chgrp commands to change ownership and group of the files. Say you have several files like this:
# ls -l
total 8
-rw-r--r--    1 shannura   users          70 Dec 12 04:02 _top_activity.sql
-rwxr-xr-x    1 oracle     dba           132 Dec 12 04:02 _top_activity1.sql
-rwxr-xr-x    1 oracle     dba           132 Dec 12 04:02 _top_sessions.sql
-rwxr-xr-x    1 oracle     dba           132 Dec 12 04:02 _top_sqls1.sql
-rwxr-xr-x    1 oracle     dba           132 Dec 12 04:02 _top_sqls2.sql
-rwxr-xr-x    1 oracle     dba           132 Dec 12 04:02 _top_sqls_hist.sql
and you need to change the permissions of all the files to match those of _top_activity1.sql. Sure, you could issue chmod 644 * to make that change. Or, perhaps you are making several permission changes and based on many different files and you find it infeasible to go though the permissions of each of those and modify accordingly.
A better approach is to make the permissions similar to those of another file. This command makes the permissions of _top_activity1.sql the same as _top_activity.sql:
chmod --reference _top_activity.sql _top_activity1.sql
Now if you check:
# ls -l _top_activity*sql
total 8
-rw-r--r--    1 shannura   users          70 Dec 12 04:02 _top_activity.sql
-rw-r--r--    1 oracle     dba           132 Dec 12 04:02 _top_activity1.sql
The '_top_activity1.sql' permissions were changed exactly as in '_top_activity.sql'. You didn’t need to get the permissions of '_top_activity.sql' first.
You can also use the same trick in group membership in files. To make the group of '_top_activity1.sql' the same as '_top_activity.sql', you would issue:
# chgrp --reference _top_activity.sql _top_activity1.sql
# ls -l _top_activity*sql
-rw-r--r--    1 shannura   users          70 Dec 12 04:02 _top_activity.sql
-rw-r--r--    1 oracle     users         132 Dec 12 04:02 _top_activity1.sql
Of course, what works for changing groups will work for owner as well. Here is how you can use the same trick for an ownership change. If permissions are like this:
# ls -l _top_activity*sql
-rw-r--r--    1 shannura   users          70 Dec 12 04:02 _top_activity.sql
-rw-r--r--    1 oracle     dba           132 Dec 12 04:02 _top_activity1.sql
You can change the ownership like this:
# chown --reference _top_activity.sql _top_activity1.sql
# ls -l _top_activity*sql
-rw-r--r--    1 shannura   users          70 Dec 12 04:02 _top_activity.sql
-rw-r--r--    1 shannura   users         132 Dec 12 04:02 _top_activity1.sql
Note that the group as well as the owner have changed.
More on files:
The 'ls' command, with its many arguments, provides some very useful information on files. A different and less well known command – stat – offers even more useful information.
Here is how you can use it on the executable "oracle", found under $ORACLE_HOME/bin.
[oracle@rhelalpha scripts]$ cd $ORACLE_HOME/bin
[oracle@rhelalpha bin]$ stat oracle
  File: `oracle'
  Size: 210824720       Blocks: 412184     IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 6181102     Links: 1
Access: (6551/-r-sr-s--x)  Uid: (  500/  oracle)   Gid: (54329/asmadmin)
Access: 2017-02-15 11:40:14.000000000 +0200
Modify: 2017-01-18 13:04:24.000000000 +0200
Change: 2017-01-18 13:37:52.000000000 +0200
The most useful part of the above output is the file access timestamp information.
When you relink Oracle (often done during patch installations), it moves the existing executables to a different name before creating the new one. For instance, you could relink all the utilities by

relink utilities
It recompiles, among other things, the sqlplus executable. It moves the exiting executable sqlplus to sqlplusO. If the recompilation fails for some reason, the relink process renames sqlplusO to sqlplus and the changes are undone. Similarly, if you discover a functionality problem after applying a patch, you can quickly undo the patch by renaming the file yourself.
Here is how you can use stat on these files:
# stat sqlplus*
  File: 'sqlplus'
  Size: 9865            Blocks: 26         IO Block: 4096   Regular File
Device: 343h/835d       Inode: 9126079     Links: 1    
Access: (0751/-rwxr-x--x)  Uid: (  500/  oracle)   Gid: (  500/     dba)
Access: 2006-08-04 05:15:18.000000000 -0400
Modify: 2006-08-04 05:15:18.000000000 -0400
Change: 2006-08-04 05:15:18.000000000 -0400
  File: 'sqlplusO'
  Size: 8851            Blocks: 24         IO Block: 4096   Regular File
Device: 343h/835d       Inode: 9125991     Links: 1    
Access: (0751/-rwxr-x--x)  Uid: (  500/  oracle)   Gid: (  500/     dba)
Access: 2006-08-04 05:13:57.000000000 -0400
Modify: 2005-11-02 11:50:46.000000000 -0500
Change: 2005-11-02 11:55:24.000000000 -0500
It shows sqlplusO was modified on November 11, 2005, while sqlplus was modified on August 4, 2006, which also corresponds to the status change time of sqlplusO . It indicates that the original version of sqlplus was in effect from Nov 11, 2005 to Aug 4, 2006. If you want to diagnose some functionality issues, this is a great place to start. In addition to the file changes, as you know the permission's change time, you can correlate it with any perceived functionality issues.
Another important output is size of the file, which is different—9865 bytes for sqlplus as opposed to 8851 for sqlplusO—indicating that the versions are not mere recompiles; they actually changed with additional libraries (perhaps). This also indicates a potential cause of some problems.
File Types
When you see a file, how do you know what type of file it is? The command file tells you that. For instance:
# file alert_DBA102.log
alert_DBA102.log: ASCII text
The file alert_DBA102.log is an ASCII text file. Let’s see some more examples:
# file initTESTAUX.ora.Z
initTESTAUX.ora.Z: compress'd data 16 bits
This tells you that the file is a compressed file, but how do you know the type of the file was compressed? One option is to uncompress it and run file against it; but that would make it virtually impossible. A cleaner option is to use the parameter -z:
# file -z initTESTAUX.ora.Z
initTESTAUX.ora.Z: ASCII text (compress'd data 16 bits)
Another quirk is the presence of symbolic links:
# file spfile+ASM.ora.ORIGINAL   
spfile+ASM.ora.ORIGINAL: symbolic link to 
This is useful; but what type of file is that is being pointed to? Instead of running file again, you can use the option -l:
# file -L spfile+ASM.ora.ORIGINAL
spfile+ASM.ora.ORIGINAL: data
This clearly shows that the file is a data file. Note that the spfile is a binary one, as opposed to init.ora; so the file shows up as data file.
Suppose you are looking for a trace file in the user dump destination directory but are unsure if the file is located on another directory and merely exists here as a symbolic link, or if someone has compressed the file (or even renamed it). There is one thing you know: it’s definitely an ascii file. Here is what you can do:

file -Lz * | grep ASCII | cut -d":" -f1 | xargs ls -ltr
This command checks the ASCII files, even if they are compressed, and lists them in chronological order.
Comparing Files
How do you find out if two files—file1 and file2—are identical? There are several ways and each approach has its own appeal.
diff. The simplest command is diff, which shows the difference between two files. Here are the contents of two files:
# cat file1
In file1 only
In file1 and file2

# cat file2
In file1 and file2
In file2 only
If you use the diff command, you will be able to see the difference between the files as shown below:
# diff file1 file2
<< In file1 only
> In file2 only
In the output, a "<" in the first column indicates that the line exists on the file mentioned first,—that is, file1. A ">" in that place indicates that the line exists on the second file (file2). The characters 1d0 in the first line of the output shows what must be done in sed to operate on the file file1 to make it same as file2.
Another option, -y, shows the same output, but side by side:
# diff -y file1 file2 -W 120
In file1 only                             <
In file1 and file2                             In file1 and file2
                                          >    In file2 only
The -W option is optional; it merely instructs the command to use a 120-character wide screen, useful for files with long lines.
If you just want to just know if the files differ, not necessarily how, you can use the -q option.
# diff -q file3 file4
# diff -q file3 file2
Files file3 and file2 differ
Files file3 and file4 are the same so there is no output; in the other case, the fact that the files differ is reported.
cmp. The command cmp is similar to diff:
# cmp file1 file2   
file1 file2 differ: byte 10, line 1
The output comes back as the first sign of difference. You can use this to identify where the files might be different. Like diff, cmp has a lot of options, the most important being the -s option, that merely returns a code:
  • 0, if the files are identical
  • 1, if they differ
  • Some other non-zero number, if the comparison couldn’t be made
This command generates a 32-bit MD5 hash value of the files:
# md5sum file1
ef929460b3731851259137194fe5ac47  file1
Two files with the same checksum can be considered identical. However, the usefulness of this command goes beyond just comparing files. It can also provide a mechanism to guarantee the integrity of the files.
Suppose you have two important files—file1 and file2—that you need to protect. You can use the --check option check to confirm the files haven't changed. First, create a checksum file for both these important files and keep it safe:
# md5sum file1 file2 > f1f2
Later, when you want to verify that the files are still untouched:
# md5sum --check f1f2      
file1: OK
file2: OK
This shows clearly that the files have not been modified. Now change one file and check the MD5:
# cp file2 file1
# md5sum --check f1f2
file1: FAILED
file2: OK
md5sum: WARNING: 1 of 2 computed checksums did NOT match
The output clearly shows that file1 has been modified.
md5sum is an extremely powerful command for security implementations. Some of the configuration files you manage, such as 'listener.ora', 'tnsnames.ora', and 'init.ora', are extremely critical in a successful Oracle infrastructure and any modification may result in downtime. These are typically a part of your change control process. Instead of just relying on someone’s word that these files have not changed, enforce it using MD5 checksum. Create a checksum file and whenever you make a planned change, recreate this file. As a part of your compliance, check this file using the md5sum command. If someone inadvertently updated one of these key files, you would immediately catch the change.

In the same line, you can also create MD5 checksums for all executables in $ORACLE_HOME/bin and compare them from time to time for unauthorized modifications.
Please write your comment if this article was useful.


You might want to read this:
Advanced Linux Commands (Part 2)