I've written a pretty long, and moderately complex Bash script that enables me to start my Node server with chosen options very easily...the problem is that it's not working correctly.
The part that is giving me trouble is here...
if netstat -an | grep ":$REQUESTED_PORT" > /dev/null
then
SERVICE_PIDS_STRING=`lsof -i tcp:$REQUESTED_PORT -t`
OLD_IFS="$IFS"
IFS='
'
read -a SERVICE_PIDS <<< "${SERVICE_PIDS_STRING}"
IFS="$OLD_IFS"
printf 'Port is in use by the following service(s)...\n\n-------------------\n\nProcess : PID\n\n'
for PID in "${SERVICE_PIDS[@]}"
do
PROCESS_NAME=`ps -p $PID -o comm=`
printf "$PROCESS_NAME : $PID\n"
done
printf "\n-------------------\n\nPlease kill the procceses utilizing port $REQUESTED_PORT and run this script again...exiting.\n"
exit
The intended function of this script is to use netstat
to test if the requested port is busy. If so, it reports the PIDs utilizing the port so that the user can kill them if they wish.
I'm fairly certain this is a problem with the way I'm using netstat
. Occasionally, the netstat
if statement will trigger, even though there is nothing using the port. lsof
is working correctly, and doesn't report any PIDs using the port.
However, when the last time the script made this error, I declared the REQUESTED_PORT
and then ran netstat -an | grep ":$REQUESTED_PORT"
. The shell did not report anything.
What is the problem with this condition that causes it to fire at inappropriate times?
EDIT
I should also mention that this machine is running Debian Jessie.
You're searching an awful lot of text, and your desired number could show up anywhere. Better to narrow the search down; and you can grab your PIDs and process names in the same step. Some other optimizations follow:
# upper case variable names should be reserved for the shell
if service_pids_string=$(lsof +c 15 -i tcp:$requested_port)
then
# make an array with newline separated string containing spaces
# note we're only setting IFS for this one command
IFS=$'\n' read -r -d '' -a service_pids <<< "$service_pids_string"
# remove the first element containing column headers
service_pids=("${service_pids[@]:1}")
printf 'Port is in use by the following service(s)...\n\n-------------------\n\nProcess : PID\n\n'
for pid in "${service_pids[@]}"
do
# simple space-separated text to array
pid=($pid)
echo "${pid[0]} : ${pid[1]}"
done
# printf should be passed variables as parameters
printf "\n-------------------\n\nPlease kill the procceses utilizing port %s and run this script again...exiting.\n" $requested_port
fi
You should run your script through shellcheck.net; it will probably find other potential issues that I haven't.