`ps --sort -cmd` on Unix is not sorting consistently on different servers - sorting

Given 2 servers, I want to print the ps for MYAPP on them.
Yet, despite the sort, both servers print QA and UAT in seemingly random orders.
(sorting by time seems to work fine)
BOTH SERVERS:
ps -ef
UID PID PPID C STIME TTY TIME CMD
..........
BOTH SERVERS:
ps -ef | sort -k 8 | grep MYAPP
ourID #### ### # Dec01 ? 02:45:00 /path/to/our/java/MYAPP_SERVICE_QA_JAVA....
ourID #### ### # Dec01 ? 06:00:00 /path/to/our/java/MYAPP_SERVICE_UAT_JAVA....
But using ps built-in sort:
#SERVER 1:
ps -ef --sort -cmd | grep MYAPP
ourID #### ### # Dec01 ? 06:00:00 /path/to/our/java/MYAPP_SERVICE_UAT_JAVA....
ourID #### ### # Dec01 ? 02:45:00 /path/to/our/java/MYAPP_SERVICE_QA_JAVA....
#SERVER 2:
ps -ef --sort -cmd | grep MYAPP
ourID #### ### # Dec01 ? 03:00:00 /path/to/our/java/MYAPP_SERVICE_QA_JAVA....
ourID #### ### # Dec01 ? 06:45:00 /path/to/our/java/MYAPP_SERVICE_UAT_JAVA....

Related

ps -ef | { head -n 1 ; sort ; } Unexpected output [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Why does the following cut out the word root on the second line and skew the output, not to be uniform to all the following lines?
# ps -ef | { head -n 1 ; sort ; } | head -n11
UID PID PPID C STIME TTY TIME CMD
470 2 0 Oct07 ? 00:00:00 [xfsaild/nvme4n1]
apache 10210 5801 0 Oct12 ? 00:04:04 /var/site/fastcgi.pl
apache 10211 5801 0 Oct12 ? 00:03:11 /var/site/fastcgi.pl
apache 10212 5801 0 Oct12 ? 00:03:35 /var/site/fastcgi.pl
apache 10265 5801 0 Oct12 ? 00:03:55 /var/site/fastcgi.pl
apache 10325 5801 0 Oct12 ? 00:03:50 /var/site/fastcgi.pl
apache 10328 5801 0 Oct12 ? 00:03:39 /var/site/fastcgi.pl
apache 10329 5801 0 Oct12 ? 00:02:59 /var/site/fastcgi.pl
apache 10330 5801 0 Oct12 ? 00:03:50 /var/site/fastcgi.pl
apache 11889 3815 0 Oct08 ? 00:33:11 /usr/sbin/httpd -k start
I'd expect output to print:
# ps -ef | { head -n 1 ; sort ; } | head -n2
UID PID PPID C STIME TTY TIME CMD
root 470 2 0 Oct07 ? 00:00:00 [xfsaild/nvme4n1]
This seems to be a Race condition. Sometimes when I run it it does not happen.
$ ps -ef | { head -n 1 ; sort ; } | head -n3
UID PID PPID C STIME TTY TIME CMD
avahi 1328 1 0 Oct12 ? 00:00:08 avahi-daemon: running [danied.local]
avahi 1401 1328 0 Oct12 ? 00:00:00 avahi-daemon: chroot helper
Your command is subject to race conditions, more specifically head -n1 could close the pipe behind before the second command manages to get any input, if the first command also has ended.
Consider this example:
> cat test.sh
for ((i=1;i<=3; i++)); do
printf "$i\n"
# sleep 1
done
If you run this many times, you will get different results
> sh test.sh | { head -n1; tail -n +1; }
1
> sh test.sh | { head -n1; tail -n +1; }
1
2
3
If you uncomment the sleep 1 statement into the loop, both commands will get input. Because the pipe will not be closed from the first command immediately, so the second part will wait for sure, although the first head is done.
When I launch this command, this is what I get:
Prompt> ps -ef | { head -n 1 ; sort ; } | head -n11
UID PID PPID C STIME TTY TIME CMD
Prompt> uname -a
Linux ...-Microsoft #488-Microsoft Mon Sep 01 13:43:00 ... GNU/Linux
This makes a lot more sense: ps -ef shows all running processes, head -n 1 only shows the first line, and the rest is not important.
Can you run that command again and see that everything is like you say, and run the uname -a command, in order to verify which type of machine you're working with? (The result of env | grep -i "shell" might be useful too). Just edit your question accordingly.

Shell script to wait till the command execute and status change

I am creating a shell script to Backup openstack cinder volume to glance image as like below.
test1 is volume name in the script.
#!/bin/bash
DATE=`date +%Y-%m-%d`
BACKUPDIR=/mnt/osbk/
declare -a VMS=(
test1
)
source /root/admin-openrc
echo $DATE `date` Starting Backup process of images
for vmname in "${VMS[#]}"
do
echo Backing up $vmname
echo cinder upload-to-image ${vmname} ${vmname}-vol-bkp --disk-format qcow2 --container-format bare --force True
cinder upload-to-image ${vmname} ${vmname}-vol-bkp --disk-format qcow2 --container-format bare --force True
echo glance image-download ${vmname}-vol-bkp --file $BACKUPDIR/${vmname}-vol-bkp-${DATE}.qcow2
glance --os-image-api-version 1 image-download ${vmname}-vol-bkp --file $BACKUPDIR/${vmname}-vol-bkp-${DATE}.qcow2
done
Output looks like this:
2018-12-29 Sat Dec 29 16:37:45 IST 2018 Starting Backup process of images
Backing up test1
cinder upload-to-image test1 test1-vol-bkp --disk-format qcow2 --container-format bare --force True
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| container_format | bare |
| disk_format | qcow2 |
| display_description | |
| id | 26c90209-8151-4136-b5de-f2ad7419b100 |
| image_id | 01e88175-a3fa-4354-8c0f-e4fafd9c9fc3 |
| image_name | test1-vol-bkp |
| is_public | False |
| protected | False |
| size | 2 |
| status | uploading |
| updated_at | 2018-12-29T11:07:00.000000 |
| volume_type | None |
+---------------------+--------------------------------------+
glance image-download test1-vol-bkp --file /mnt/osbk//test1-vol-bkp-2018-12-29.qcow2
404 Not Found
The resource could not be found.
Image 01e88175-a3fa-4354-8c0f-e4fafd9c9fc3 is not active (HTTP 404)
From above output the status is uploading...
I need to hold my script to wait or check the status of volume change to Active, then only the glance image download command has to run.
What am I doing wrong?

How to assure the selection of an open port in shell

So I have a script that creates a tunnel. To do that it uses random ports.
This is the logic for random port generation
RPORT=1
while [ $RPORT -lt 2000 ]
do
RPORT=$[($RANDOM % 3000) + 1]
done
This is good only if the port that it selects isn't in use. If that port is active, I am unable to access that server while that port is being used.
I want to do something like this
while [netsat -nat | grep $RPORT] = true
do
RPORT=$[($RANDOM % 3000) + 1]
So I want to check first if that port is in use, if so, search for another random port, check if it is in use, if no then use it.
Thank you very much in advance for you time and help!
function random_unused_port {
(netstat --listening --all --tcp --numeric |
sed '1,2d; s/[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*:\([0-9]*\)[[:space:]]*.*/\1/g' |
sort -n | uniq; seq 1 1000; seq 1 65535
) | sort -n | uniq -u | shuf -n 1
}
RANDOM_PORT=$(random_unused_port)
This was the function that helped me out!
Thank you Nahuel Fouilleul for the link!
To fix the answer, also because port from 1 to 1000 are reserved seq starts at 1001
grep -F -x -v -f <(
netstat --listening --all --tcp --numeric |
sed '1,2d; s/[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*:\([0-9]*\)[[:space:]]*.*/\1/g' |
sort -nu
) <(seq 1001 65536) | shuf -n 1

Formatting grep output. Bash

trying to format output from grep to make it look better, code is
grep "$1" "$2" | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" | sort | uniq -c
$ bash myScript.sh "Failed password for root" /home/user/auth.log
5 108.166.98.9
1426 108.53.208.61
1 113.108.211.131
1 117.79.91.195
370 122.224.49.124
3480 144.0.0.32
11 162.144.94.250
6 162.253.66.74
3 186.67.83.58
1 222.190.114.98
205 59.90.242.69
705 60.172.228.226
3 64.251.21.104
and want it to look more like
ip: xxx.xxx.xxx.xxx attempts: X
Add the following command to the end of your pipe in your script, after uniq:
... | awk '{print "ip: " $2 " attempts: " $1}'
The output will be
ip: 108.166.98.9 attempts: 5
ip: 108.53.208.61 attempts: 1426
...

Can't get correct output from command `ps -eaf | grep groovy` using groovy

If I use shell:
ps -eaf | grep groovy
I can get such output:
[root#test www]# ps -eaf | grep groovy
root 924 539 1 03:15 pts/0 00:00:05 /usr/java/jdk1.6.0_31/bin/java -classpath
/root/dev/groovy-1.8.8/lib/groovy-1.8.8.jar -Dscript.name=./groovysh -Dprogram.name=groovysh
-Dgroovy.starter.conf=/root/dev/groovy-1.8.8/conf/groovy-starter.conf
-Dgroovy.home=/root/dev/groovy-1.8.8 -Dtools.jar=/usr/java/jdk1.6.0_31/lib/tools.jar
org.codehaus.groovy.tools.GroovyStarter --main org.codehaus.groovy.tools.shell.Main
--conf /root/dev/groovy-1.8.8/conf/groovy-starter.conf --classpath .
root 1127 562 0 03:20 pts/1 00:00:00 grep groovy
[root#test www]#
But if I run this command in groovy:
proc = "ps -eaf | grep groovy".execute()
proc.waitFor() // => return 1
proc.in.text // => return ""
proc.err.text // => see following
The proc.err.text will be the document of ps command:
ERROR: Garbage option.
********* simple selection ********* ********* selection by list *********
-A all processes -C by command name
-N negate selection -G by real group ID (supports names)
-a all w/ tty except session leaders -U by real user ID (supports names)
-d all except session leaders -g by session OR by effective group name
-e all processes -p by process ID
T all processes on this terminal -s processes in the sessions given
But if I run ps -eaf it will be correct.
It seems | can't be used, is it true? How to fix it?
Yeah, you can't use shell output piping and redirection like that.
One option is to do:
Process ps = 'ps -eaf'.execute()
Process gr = 'grep groovy'.execute()
Process all = ps | gr
println all.text
The other is to wrap it in a new shell using the List form of execute:
println( [ 'sh', '-c', 'ps -eaf | grep groovy' ].execute().text )

Resources