Korn Shell Operators

I write $SHELL scripts most days, I am always looking these two tables up on other sites rather than commit them to memory, so why not just post it here so I know where to find it forever more. We mostly use ksh over bash as ksh is on every system regardless of age of that host.

ItemDescription
-a FileTrue, if the specified file is a symbolic link that points to another file that does exist.
-b FileTrue, if the specified file exists and is a block special file.
-c FileTrue, if the specified file exists and is a character special file.
-d FileTrue, if the specified file exists and is a directory.
-e FileTrue, if the specified file exists.
-f FileTrue, if the specified file exists and is an ordinary file.
-g FileTrue, if the specified file exists and its setgid bit is set.
-h FileTrue, if the specified file exists and is a symbolic link.
-k FileTrue, if the specified file exists and its sticky bit is set.
-n StringTrue, if the length of the specified string is nonzero.
-o OptionTrue, if the specified option is on.
-p FileTrue, if the specified file exists and is a FIFO special file or a pipe.
-r FileTrue, if the specified file exists and is readable by the current process.
-s FileTrue, if the specified file exists and has a size greater than 0.
-t FileDescriptorTrue, if specified file descriptor number is open and associated with a terminal device.
-u FileTrue, if the specified file exists and its setuid bit is set.
-w FileTrue, if the specified file exists and the write bit is on. However, the file will not be writable on a read-only file system even if this test indicates true.
-x FileTrue, if the specified file exists and the execute flag is on. If the specified file exists and is a directory, then the current process has permission to search in the directory.
-z StringTrue, if length of the specified string is 0.
-L FileTrue, if the specified file exists and is a symbolic link.
-O FileTrue, if the specified file exists and is owned by the effective user ID of this process.
-G FileTrue, if the specified file exists and its group matches the effective group ID of this process.
-S FileTrue, if the specified file exists and is a socket.
File1 -nt File2True, if File1 exists and is newer than File2.
File1 -ot File2True, if File1 exists and is older than File2.
File1 -ef File2True, if File1 and File2 exist and refer to the same file.
String1 = String2True, if String1 is equal to String2.
String1 != String2True, if String1 is not equal to String2.
String = PatternTrue, if the specified string matches the specified pattern.
String != PatternTrue, if the specified string does not match the specified pattern.
String1 < String2True, if String1 comes before String2 based on the ASCII value of their characters.
String1 > String2True, if String1 comes after String2 based on the ASCII value of their characters.
Expression1 -eq Expression2True, if Expression1 is equal to Expression2.
Expression1 -ne Expression2True, if Expression1 is not equal to Expression2.
Expression1 -lt Expression2True, if Expression1 is less than Expression2.
Expression1 -gt Expression2True, if Expression1 is greater than Expression2.
Expression1 -le Expression2
True, if Expression1 is less than or equal to Expression2.
Expression1 -ge Expression2True, if Expression1 is greater than or equal to Expression2.

You can combine expressions together like below;

ItemDescription
(Expression)
True, if the specified expression is true. Used to group expressions.
! ExpressionTrue, if the specified expression is false.
Expression1 && Expression2True, if Expression1 and Expression2 are both true.
Expression1 || Expression2True, if either Expression1 or Expression2 is true.

Weekly script #3 unix_usr.sql

I use this one all the time. You have a high usage unix PID that is an Oracle Process. The script will take your defined pid and lookup the relating SQL and database user details to help you figure out the root cause.


set serveroutput on size 50000
set echo off feed off veri off
accept 1 prompt 'Enter Unix process id: '

DECLARE
v_sid number;
s sys.v_$session%ROWTYPE;
p sys.v_$process%ROWTYPE;
BEGIN
begin
select sid into v_sid
from sys.v_$process p, sys.v_$session s
where p.addr = s.paddr
and (p.spid = &&1
or s.process = '&&1');
exception
when no_data_found then
dbms_output.put_line('Unable to find process id &&1!!!');
return;
when others then
dbms_output.put_line(sqlerrm);
return;
end;

select * into s from sys.v_$session where sid = v_sid;
select * into p from sys.v_$process where addr = s.paddr;

dbms_output.put_line('=====================================================================');
dbms_output.put_line('SID/Serial : '|| s.sid||','||s.serial#);
dbms_output.put_line('Foreground : '|| 'PID: '||s.process||' - '||s.program);
dbms_output.put_line('Shadow : '|| 'PID: '||p.spid||' - '||p.program);
dbms_output.put_line('Terminal : '|| s.terminal || '/ ' || p.terminal);
dbms_output.put_line('OS User : '|| s.osuser||' on '||s.machine);
dbms_output.put_line('Ora User : '|| s.username);
dbms_output.put_line('Status Flags: '|| s.status||' '||s.server||' '||s.type);
dbms_output.put_line('Tran Active : '|| nvl(s.taddr, 'NONE'));
dbms_output.put_line('Login Time : '|| to_char(s.logon_time, 'Dy HH24:MI:SS'));
dbms_output.put_line('Last Call : '|| to_char(sysdate-(s.last_call_et/60/60/24), 'Dy HH24:MI:SS') || ' - ' || to_char(s.last_call_et/60, '990.0') || ' min');
dbms_output.put_line('Lock/ Latch : '|| nvl(s.lockwait, 'NONE')||'/ '||nvl(p.latchwait, 'NONE'));
dbms_output.put_line('Latch Spin : '|| nvl(p.latchspin, 'NONE'));

dbms_output.put_line('Current SQL statement:');
for c1 in ( select * from sys.v_$sqltext
where HASH_VALUE = s.sql_hash_value order by piece) loop
dbms_output.put_line(chr(9)||c1.sql_text);
end loop;

dbms_output.put_line('Previous SQL statement:');
for c1 in ( select * from sys.v_$sqltext
where HASH_VALUE = s.prev_hash_value order by piece) loop
dbms_output.put_line(chr(9)||c1.sql_text);
end loop;

dbms_output.put_line('Session Waits:');
for c1 in ( select * from sys.v_$session_wait where sid = s.sid) loop
dbms_output.put_line(chr(9)||c1.state||': '||c1.event);
end loop;

-- dbms_output.put_line('Connect Info:');
-- for c1 in ( select * from sys.v_$session_connect_info where sid = s.sid) loop
-- dbms_output.put_line(chr(9)||': '||c1.network_service_banner);
-- end loop;

dbms_output.put_line('Locks:');
for c1 in ( select /*+ ordered */
decode(l.type,
-- Long locks
'TM', 'DML/DATA ENQ', 'TX', 'TRANSAC ENQ',
'UL', 'PLS USR LOCK',
-- Short locks
'BL', 'BUF HASH TBL', 'CF', 'CONTROL FILE',
'CI', 'CROSS INST F', 'DF', 'DATA FILE ',
'CU', 'CURSOR BIND ',
'DL', 'DIRECT LOAD ', 'DM', 'MOUNT/STRTUP',
'DR', 'RECO LOCK ', 'DX', 'DISTRIB TRAN',
'FS', 'FILE SET ', 'IN', 'INSTANCE NUM',
'FI', 'SGA OPN FILE',
'IR', 'INSTCE RECVR', 'IS', 'GET STATE ',
'IV', 'LIBCACHE INV', 'KK', 'LOG SW KICK ',
'LS', 'LOG SWITCH ',
'MM', 'MOUNT DEF ', 'MR', 'MEDIA RECVRY',
'PF', 'PWFILE ENQ ', 'PR', 'PROCESS STRT',
'RT', 'REDO THREAD ', 'SC', 'SCN ENQ ',
'RW', 'ROW WAIT ',
'SM', 'SMON LOCK ', 'SN', 'SEQNO INSTCE',
'SQ', 'SEQNO ENQ ', 'ST', 'SPACE TRANSC',
'SV', 'SEQNO VALUE ', 'TA', 'GENERIC ENQ ',
'TD', 'DLL ENQ ', 'TE', 'EXTEND SEG ',
'TS', 'TEMP SEGMENT', 'TT', 'TEMP TABLE ',
'UN', 'USER NAME ', 'WL', 'WRITE REDO ',
'TYPE='||l.type) type,
decode(l.lmode, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX',
4, 'S', 5, 'RSX', 6, 'X',
to_char(l.lmode) ) lmode,
decode(l.request, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX',
4, 'S', 5, 'RSX', 6, 'X',
to_char(l.request) ) lrequest,
decode(l.type, 'MR', o.name,
'TD', o.name,
'TM', o.name,
'RW', 'FILE#='||substr(l.id1,1,3)||
' BLOCK#='||substr(l.id1,4,5)||' ROW='||l.id2,
'TX', 'RS+SLOT#'||l.id1||' WRP#'||l.id2,
'WL', 'REDO LOG FILE#='||l.id1,
'RT', 'THREAD='||l.id1,
'TS', decode(l.id2, 0, 'ENQUEUE', 'NEW BLOCK ALLOCATION'),
'ID1='||l.id1||' ID2='||l.id2) objname
from sys.v_$lock l, sys.obj$ o
where sid = s.sid
and l.id1 = o.obj#(+) ) loop
dbms_output.put_line(chr(9)||c1.type||' H: '||c1.lmode||' R: '||c1.lrequest||' - '||c1.objname);
end loop;

dbms_output.put_line('=====================================================================');

END;
/

undef 1

Weekly script #2 pid_from_sid.sql

A fairly easy script today that isn’t really hard to work out for yourself but I find it useful to have this script kicking around for when you find high resource using Oracle server process and you want to identify the offending SQL.


set pages 1000;
set lines 200;
col username for a10;

select b.status,a.inst_id,a.PID "Ora PID",a.SPID "Server PID",
a.LATCHWAIT,b.Program, b.Username,b.Osuser,b.machine,
b.terminal,a.terminal,b.Process "Client Process"
from gv$process a,gv$session b where a.addr=b.paddr and b.sid=&SID
/

See you next week!

Le Paz
 

 

Weekly Script #1 – ssh_key_scp.sh

Since I dont post on here to often I will try and post a weekly script that I find useful day-to-day.

First up is a short simple script to scp your private key to a defined server. Usage is pretty simple call the script with the username@hostname

e.g ./ssh_key_scp.sh username@hostname

If no ssh key already exists the script gives you the option to generate one.


#!/bin/sh
# Andrew Paz
# 06/01/15
#

KEY="$HOME/.ssh/id_rsa.pub"

if [ ! -f ~/.ssh/id_rsa.pub ];then
echo "Private key not found at $KEY"
while true; do
read -p "Do you wish to generate a private key?" yn
case $yn in
[Yy]* ) ssh-keygen -t rsa; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no!";;
esac
done
exit

fi

if [ -z $1 ];then
echo "Please specify user@host as the first parameter of this script"
exit
fi

echo "Putting your key on $1... "

KEYCODE=`cat $KEY`
ssh -q $1 "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "$KEYCODE" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"

echo "done :D Key Uploaded!"

exit;
end

Thats it for this week, will post another next week.

Cheers

A better Oracle DAC startserver.sh

Just want to share my Oracle DAC 10g startserver.sh.

startserver.sh is already provides as part of the DAC 10g install. I have added a couple of extra java parameters to allow a larger heap size and garbage collection method

. ./config.sh

$JAVA -server -Xms2048m -Xmx2048m -XX:+UseParNewGC -XX:ErrorFile='./hs_err_pid.log' -cp $DACCLASSPATH com.siebel.etl.net.QServer

-Xms and -Xmx give the dac server application 2GB of heap size to play with.

-XX:+UseParNewGC forces JVM to use parallel young generation GC with the concurrent GC.

-XX:ErrorFile should your dac server crash with a JVM error the stacktrace/dump will be stored in the specified file.

Until I feel like posting again ūüėČ

Check Node Manager Script

Hi Again,

I just knocked up this nodemanager check script that you can run as a cron job making sure the Weblogic Java NodeManager is running and if not email you. See below for the script.


#!/bin/ksh
 #
 #########################################################
 # NAME:check_node_manager.sh #
 # AUTHOR: Paz #
 # DESC: Check no make sure Weblogic Node Manager is #
 # running #
 # DATE: 19/06/13 #
 # VERSION 1.0 #
 # CHANGE LOG: #
 # AP 19/06/2013 Creation #
 # #
 # #
 #########################################################
 #
 #set -x

. $HOME/.profile
 export SCRIPT_HOME='add you scripts home'
 ####################CHECK NODE MANAGER JAVA PROCESS IS RUNNING########################
 cd $SCRIPT_HOME

jps |grep -i NodeManager >Nodemgr_jps_status.log

sleep 2

nodemgr_jps_status=$(cat Nodemgr_jps_status.log |grep -i 'NodeManager' |wc -l)

if [ ${nodemgr_jps_status} -gt 0 ]
 then
 echo 'do nothing Node Manager Alive'
 else
 mailx -s 'NODEMANAGER DOWN' your@email.com
 fi

exit

EOF

The script can be changed if you use a script based nodemanager, if you change ‘jps’ for ‘ps -ef’ so the line would read:

ps -ef |grep -i NodeManager >Nodemgr_jps_status.log

Until next time

Adding Colour to Solaris 10

I have spent hours trolling the net looking for a definitive guide on how to make colours (color if you are from the US) work in Solaris 10.

By default colour isn’t enabled but once you know how it is¬†relativity¬†easy to get it to work.

The first step is to download a number of new packages from http://www.sunfreeware.com the packages needed are as follows:

coreutils-8.19-sol10-sparc-local
gmp-4.2.1-sol10-sparc-local
libiconv-1.14-sol10-sparc-local
gcc-3.4.6-sol10-sparc-local
libgcc-3.3-sol10-sparc-local
libintl-3.4.0-sol10-sparc-local

After all the packages are downloaded and added to your Solaris machine it time to install them using pkgadd.

Get root on your machine and install the packages

su

pkgadd -d coreutils-8.19-sol10-sparc-local

Do this for each of the downloaded packages.

The next step is to test that colours are now working run the following command to check.

/usr/local/bin/ls –color ¬† ¬†(this command assumes that you have installed the packages in the¬†default¬†location)

Now that colour is working we just need to modify the profile so that it always works.

Depending on your shell you may need to edit .profile for ksh or .bashrc for bash.

Update PATH by adding the new location to it:

export PATH=$PATH:/usr/local/bin

now if you run;

which ls

its should return /usr/local/bin/ls

add an alias to your profile to append –color to ls command

alias ls=’/usr/local/bin/ls –color’

Reload your profile and type ls, the results should return in colour.

The final section of this guide is to change the colour of your shell prompt you can do so by adding the folowing command to your profile

export PS1=”\e[0;35m\u@\h > \e[m”

You can set the colour to any of the below by editing the number;

Color Code
Black     0;30
Blue       0;34
Green    0;32
Cyan      0;36
Red        0;31
Purple  0;35
Brown  0;33
Blue      0;34
Green   0;32
Cyan    0;36
Red      0;31
Purple 0;35
Brown 0;33

You should now have a fully coloured SHELL prompt.