Application Status script - linux

I have a start and stop script in-place and need a script that gives status on Linux server. My start script looks as below, can you please let me know if I can add some arguments/command to get my application status.
#!/bin/ksh
java_home=`cat /apps/abc.properties | grep "$1|" | cut "-d|" -f2`
service_executable=`cat /apps/abc.properties | grep "$1|" | cut "-d|" -f3`
service_home=`cat /apps/abc.properties | grep "$1|" | cut "-d|" -f4`
service_opts=`cat /apps/abc.properties | grep "$1|" | cut "-d|" -f5`
export JAVA_HOME=$java_home
export PATH=$JAVA_HOME/bin:$PATH
echo start $service_home
cd $service_home/bin
nohup $service_executable start $service_opts
abc.properties has below values
abc-3.7.3|/apps/java/jdk1.8.0_66|rmc|/apps/rmc/abc-3.7.3|-M-Drmc.mmc.bind.port=8770
abc-3.7.3-spii|/apps/java/jdk1.8.0_66|rmc|/apps/rmc/abc-3.7.3-spii|-M-Drmc.mmc.bind.port=8770
I want a scrpit that can check each version of application(JVM) using port numbers and give me status for example abc-3.7.3"running"/ abc-3.7.3-spii"down".

A quick version would be to have a script that would extract the application name and the port number form the input file (ex. read APP + stuff + PORT) and then check if the port is opened (ex. in the netstat output grep for the port number).
This is a very short form that does just that:
while IFS="|=" read App _ _ _ _ Port; do
netstat -lnt | grep -qw ":$Port" && echo "$App : running" || echo "$App : down"
done < abc.properties
Is it good enough?

Thanks for your answer, I tried using " if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; "and it worked fine on RHEL6 (4.82) but on RHEL5 I'm seeing a error below
lsof: unsupported TCP/TPI info selection: C
lsof: unsupported TCP/TPI info selection: P
lsof: unsupported TCP/TPI info selection: :
lsof: unsupported TCP/TPI info selection: L
lsof: unsupported TCP/TPI info selection: I
lsof: unsupported TCP/TPI info selection: S
lsof: unsupported TCP/TPI info selection: T
lsof: unsupported TCP/TPI info selection: E
lsof: unsupported TCP/TPI info selection: N
lsof 4.78

Related

ENOTTY error when execute pm2 from a pm2 process

Let us say I have this very simple python command that wraps a call to "pm2 ls":
python3 -c "import subprocess; subprocess.run(['pm2', 'ls'])"
Now, let us run this same command, but within a pm2 start:
pm2 start -n "test" "python3 -c \"import subprocess; subprocess.run(['pm2', 'ls'])\""
If I check pm2 logs, I can see it fails with the message below (output of pm2 log test)
0|test | child_process.js:159
0|test | p.open(fd);
0|test | ^
0|test |
0|test | Error: ENOTTY: inappropriate ioctl for device, uv_pipe_open
0|test | at Object._forkChild (child_process.js:159:5)
0|test | at setupChildProcessIpcChannel (internal/bootstrap/pre_execution.js:356:30)
0|test | at prepareMainThreadExecution (internal/bootstrap/pre_execution.js:53:3)
0|test | at internal/main/run_main_module.js:7:1 {
0|test | errno: -25,
0|test | code: 'ENOTTY',
0|test | syscall: 'uv_pipe_open'
0|test | }
Now, if I change subprocess.run() with os.spawnlp() as below:
pm2 start -n test2 "python -c \"import os; os.spawnlp(os.P_WAIT, 'pm2', 'pm2', 'ls')\""
It runs fine.
My question is:
what is the difference between subprocess.run() and os.spawnlp() in this context?
is there a way to make this work with subprocess.run()?
By the way I use:
python 3.9.10
pm2 5.1.1
node 14.17.5
macOS 13.1

Linux man command about [OPTIONS]

Let's say git add command.When I input man git add,I get its page.
SYNOPSIS
git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
[--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
[--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]
[--] [<pathspec>...]
I have two quesions:
git add --verbose is same as git add -v?
for other command such as git,python , --fullNameA is same as -A? (fullNameA is abbreviated to A)
Each option in [--xxx | -x] characters are the same, so [--verbose | -v] means that --verbose will do the same as -v. This is true for all the man pages.

linux bash cut one row which starts with a certain string

Good day,
im using linux bash commands to extract certain data of each sip account and put them next to each other.
i have an array called $peers that i put all 1000 sips into and now i need to for loop through them to set every sip to its useragent.
what i have so far is
#! /bin/bash
peers="$(asterisk -rx "sip show peers" | cut -f1 -d" " | cut -f1 -d"/" "=")" "= " asterisk -rx "sip show peer " $peer | cut -f2 -d"Useragent"
for peer in $peers do
echo $peers
done
#echo $peers
I need to extract a row from a collection of rows that starts with "Useragent"
I start by running asterisk -rx "sip show peer 101" and that gives me the result below
* Name : 101
Description :
Secret : <Set>
MD5Secret : <Not set>
Remote Secret: <Not set>
Context : outgoing
Record On feature : automon
Record Off feature : automon
Subscr.Cont. : <Not set>
Language :
Tonezone : <Not set>
AMA flags : Unknown
Transfer mode: open
CallingPres : Presentation Allowed, Not Screened
Callgroup :
Pickupgroup :
Named Callgr :
Nam. Pickupgr:
MOH Suggest :
Mailbox :
VM Extension : asterisk
LastMsgsSent : 0/0
Call limit : 0
Max forwards : 0
Dynamic : Yes
Callerid : "" <>
MaxCallBR : 384 kbps
Expire : 23
Insecure : no
Force rport : Yes
Symmetric RTP: Yes
ACL : No
DirectMedACL : No
T.38 support : No
T.38 EC mode : Unknown
T.38 MaxDtgrm: -1
DirectMedia : Yes
PromiscRedir : No
User=Phone : No
Video Support: No
Text Support : No
Ign SDP ver : No
Trust RPID : No
Send RPID : No
Subscriptions: Yes
Overlap dial : Yes
DTMFmode : rfc2833
Timer T1 : 500
Timer B : 32000
ToHost :
Addr->IP : xxx.xxx.xxx.xxx:5060
Defaddr->IP : (null)
Prim.Transp. : UDP
Allowed.Trsp : UDP
Def. Username: 101
SIP Options : (none)
Codecs : (gsm|ulaw|alaw|g729|g722)
Codec Order : (gsm:20,g722:20,g729:20,ulaw:20,alaw:20)
Auto-Framing : No
Status : OK (9 ms)
Useragent : UniFi VoIP Phone 4.6.6.489
Reg. Contact : sip:101#xxx.xxx.xxx.xxx:5060;ob
Qualify Freq : 60000 ms
Keepalive : 0 ms
Sess-Timers : Accept
Sess-Refresh : uas
Sess-Expires : 1800 secs
Min-Sess : 90 secs
RTP Engine : asterisk
Parkinglot :
Use Reason : No
Encryption : No
Now i need to cut this part Useragent : UniFi VoIP Phone 4.6.6.489
and display it as 101 : UniFi VoIP Phone 4.6.6.489
any help would be much appreciated
Thank you. that top answer worked perfectly. this is my solution now.
peer="$(asterisk -rx "sip show peers" | cut -f1 -d" " | cut -f1 -d"/" )"
for peer in $peers do
output= "$(asterisk -rx "sip show peer $peers" | sed -nE '/Useragent/ s/^[^:]+/101 /p')"
echo $output
done
But is is still giving issue, my problem is the loop of the variables
With sed:
... | sed -nE '/Useragent/ s/^[^:]+/101 /p'
/Useragent/ matches line(s) with Useragent it
s/^[^:]+/101 substitutes the portion from start till : (exclusive) with 101

How to delete the data in Character device

I have written some data into my character device in /dev/my_char.
What should I do to delete the data without removing the device from the kernel ? .
The method which I follow to delete the contents is to
1) rm /dev/my_char and
2) rmmod My_Char.
But by using this method, I have to insert the module again into the kernel and create the device in dev folder which is a lengthy process.
Using only rm /dev/my_char doesn't delete its contents.
I would like to know if there is any other method other than this.
You could implement an ioctl to reset the input buffer.
Add an ioctl handler to the driver.
Add the entry point to the file_operations structure. .unlocked_ioctl =(your function name)
For the case of the correct ioctl command, reset the buffer pointer(s), clear the count, or whatever is needed to make the device look empty.
Or you could write a script to remove the driver and reload it. Here is what I use (I call it reload):
#!/bin/bash
if [ -d /device/my_device ]; then
sudo rmmod my_device.ko
fi
VERBOSE=0
MESSAGES=0
VENDOR=
DEVICEID=
while (( $# > 0 ))
do
arg="$1"
shift
case $arg in
v=* | ve=* | ver=* | verb=* | verbo=* | verbos=* | verbose=*)
VERBOSE=${arg#*=}
;;
v | ve | ver | verb | verbo | verbos | verbose)
VERBOSE=1
;;
t | tt | tty)
MESSAGES=1
;;
ven=* | vend=* | vendo=* | vendor=*)
VENDOR="opt_vendor_id=${arg#*=}"
;;
ven | vend | vendo | vendor)
VENDOR="opt_vendor_id=$1"
shift
;;
d=* | de=* | dev=* | devi=* | devic=* | device=*)
DEVICEID="opt_device_id=${arg#*=}"
;;
d | de | dev | devi | devic | device)
DEVICEID="opt_device_id=$1"
shift
;;
*)
echo "Invalid option '$arg':"
echo "Options are 'verbose', 'tty', 'vendor='<vendor number>, and 'deviceid='<device id>"
exit 1
;;
esac
done
echo "insmod my_device.ko opt_verbose=$VERBOSE opt_tty_msgs=$MESSAGES $VENDOR $DEVICEID"
sudo insmod my_device.ko opt_verbose=$VERBOSE opt_tty_msgs=$MESSAGES $VENDOR $DEVICEID
This has a lot of extra complexity to handle parameters which are passed to the module when it is loaded. If you don't have any module parameters, the above can be simplified to:
#!/bin/bash
if [ -d /device/my_device ]; then
sudo rmmod my_device.ko
fi
sudo insmod my_device.ko
You can work with your character device as if it is a generic file
cat /dev/null > /dev/my_char
Its possible to delete the data in the device by just removing the module from the kernel and then loading the module again to the kernel.ie "rmmod My_Char" and again "insmod My_Char".By this method we need not create the device again in the /dev/my_char as it will be automatically loaded with no data.

How do i cut section with start and end using Bash?

When i am doing pactl list i get lot of information. Out of those information, i am trying to only get the part start with Sink #0 till end of that section.
1) Information's
Sink #0
State: SUSPENDED
Name: auto_null
Description: Dummy Output
Driver: module-null-sink.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 14
Mute: no
Volume: 0: 0% 1: 0%
0: -inf dB 1: -inf dB
balance 0.00
Base Volume: 100%
0.00 dB
Monitor Source: auto_null.monitor
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Dummy Output"
device.class = "abstract"
device.icon_name = "audio-card"
Source #0
State: SUSPENDED
Name: auto_null.monitor
Description: Monitor of Dummy Output
Driver: module-null-sink.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 14
Mute: no
Volume: 0: 80% 1: 80%
0: -5.81 dB 1: -5.81 dB
balance 0.00
Base Volume: 100%
0.00 dB
Monitor of Sink: auto_null
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Monitor of Dummy Output"
device.class = "monitor"
device.icon_name = "audio-input-microphone"
2) I am trying, such as:
#!/bin/bash
command=$(pactl list);
# just get Sink #0 section not one line
Part1=$(grep "Sink #0" $command);
for i in $Part1
do
# show only Sink #0 lines
echo $i;
done
3) It output very strange
grep: dB: No such file or directory
How can i get that section using my BASH script, is there any other best way to work on such filtering?
Follow up: So i was also trying to keep it simple. such as:
pactl list | grep Volume | head -n1 | cut -d' ' -f2- | tr -d ' '
|________| |________| |______| |_____________| |_________|
| | | | |
command target get show 1 row cut empty Dont know..
to list
You can use several features of the sed editor to achieve your goal.
sed -n '/^Sink/,/^$/p' pactl_Output.txt
-n says "don't perform the standard option of printing each line of output
/^Sink/,/^$/ is a range regular expr, that says find a line that begins with Sink, then keep looking at lines until you find an empty line (/^$/).
the final char, p says Print what you have matched.
If there are spaces or tabs on the empty line, use " ...,/^$[${spaceChar}${tabChar}]*\$/p". Note the change from single quoting to dbl-quoting which will allow the variables ${spaceChar} and ${tabChar} to be expanded to their real values. You may need to escape the closing '$'. YOu'll need to define spaceChar and tabChar before you use them, like spaceChar=" " . No way here on S.O. for you to see the tabChar, but not all sed's support the \t version. It's your choice to go with pressing tab key or use \t. I would go with tab key as it is more portable.
While it is probably possible to accomplish your goal with bash, sed was designed for this sort of problem.
I hope this helps.
Try:
Part1=`echo $command | grep "Sink #0"`
instead of
Part1=$(grep "Sink #0" $command);

Resources