Error when awk command's parameter is being used in pattern - bash

I'm running these commands:
ps -ef | awk -v piddd="$child_pid" '$2 ~ /\<piddd\>/ { print $3; }'
ps -ef | awk -v piddd="$child_pid" '$2 ~ /piddd/ { print $3; }'
It doesn't give me any result. When I try with this one, I get what I need, although in some cases I'll get additional pids:
ps -ef | awk -v piddd="$child_pid" '$2 ~ piddd { print $3; }'
What is wrong with first ones?

You cannot use a variable with the /pattern/ syntax.
If you want to add word boundaries (and your version of awk supports the syntax), you can do so by concatenating strings:
ps -ef | awk -v piddd="$child_pid" '$2 ~ "\\<" piddd "\\>" { print $3 }'
Note that the \ must be escaped in this case.
If you just want the whole field to match the exact variable, I'd suggest using a simple string comparison:
ps -ef | awk -v piddd="$child_pid" '$2 == piddd { print $3 }'

There isn't a need to parse the output of ps utility just to get the parent pid PPID of a child PID. The ps utility already provides this functionality.
ps -o ppid= -p $child_pid
The parameter -o ppid= tells ps to just print the parent pid. Without = the printout will contain a header PPID.
The parameter -p $child_pid tells ps to get the process information from the process id identified by variable $child_pid.

ps -ef | awk '$2 ~ /'`echo "$child_pid"`'/ { print $3; }'
# or
ps -ef | awk '$2 ~ /'$child_pid'/ { print $3; }'
# or create function
function father_pid() { ps -ef | awk '$2 ~ /'$1'/ { print $3; }'; }
# use function
father_pid $child_pid

Related

Grep command list bin/bash or dash

Is there a grep command that lists all users (in /etc/passwd) who use either bash (/bin/bash) or dash (/bin/sh) and their home directory is in /home (second to last section of: has home directory)?
I am thinking of commands:
getent passwd | awk -F ':' '$6 ~ "^/home" {print $1}'
or :
getent passwd| awk -F ":" '$7=="/bin/bash" { print $1 }'
but I am wrong.
Just combine your conditions:
getent passwd | awk -F':' '$7 ~ "^/bin/(ba)?sh$" && $6 ~ "^/home/"{ print $1 }'
or
getent passwd | awk -F':' '($7=="/bin/bash" || $7=="/bin/sh") && $6 ~ "^/home/"{ print $1 }'
The grep command that satisfies your conditions is as follows:
getent passwd | grep -E ':/home/.*?:.*?[bd]ash$'
The regex is all the lines with a home directory and bash or dash.

One-liner to retrieve path from netstat port

I'm looking to create a one liner that, given a port number (2550) uses the returned value from netstat would allow me to then run the resulting output against ps -ef to return the path of the process in question. I have:
ps -ef | grep $(netstat -tonp | grep 2550 | awk '{split($7,a,"/"); print a[1]}')
and whilst I know
netstat -tonp | grep 2550 | awk '{split($7,a,"/"); print a[1]}'
returns the expected resulted, the subsequent grep tells me that there is no such file or directory (but, if I do the ps -ef | grep **) it works just fine... I'm obviously missing something... well, obvious, but I can't see what?
try something like (it takes the first PID/port corresponding, not all):
Port=2550;ps -f --pid $( netstat -tonp | awk -F '[ \t/]+' -v Port=$Port '$0 ~ "([0-9]+[.:]){4}" Port { PID= $7;exit}; END { print PID+0 }' ) | sed 's/^\([^ \t]*[ \t]*\)\{7\}//'
the last sed is assuming a ps reply like this (space are important):
usertest 4408 4397 0 09:43 pts/6 00:00:00 ssh -p 22 -X -l usertest 198.198.131.136
for every PID and with no ending sed:
Port=2550; ps -ef | awk -v PIDs="$( netstat -tonp | awk -F '[ \t/]+' -v Port=${Port} '$0 ~ (":" Port) { print $7}' )" 'BEGIN{ split( PIDs, aTemp, /\n/); for( PID in aTemp) aPID[ aTemp[PID] ] }; $2 in aPID { sub( /^([^ \t]*[ \t]*){7}/, ""); print}'
This will give you the pids:
<sudo> netstat -tulpen | awk '$4 ~ /:2550$/{sub("/.*","",$NF);print $NF}'
You can use xargs to pass the pid to ps:
netstat -tulpen | awk '$4 ~ /:2550$/{sub("/.*","",$NF);print $NF}' | xargs -P 1 ps -o pid,cmd -p

how to using variables in search pattern in awk script

I want to print the pid when finding matched process while the match pattern is inputted:
ps aux | awk -v in="$1" '/in/{print $1}'
It seems the former awk sentence is not right. After checking many results in google like this, I change my script in the following but still cannot work:
ps aux | awk -v in="$1" '/$0 ~ in/{print $1}'
or
ps aux | awk -v in="$1" '($0 ~ in) {print $1}'
You are fairly close in all your attempts. Problem is that in is a reserved keyword in awk.
You can use:
ps aux | awk -v var="$1" '$0 ~ var {print $1}'
Or else non-regex way:
ps aux | awk -v var="$1" 'index($0, var) {print $1}'

Bash process id query

I just saw a code with a check in if as
for x in `ps -ef | awk '{ print $2 }'`
do
if [ "$x" != "PID" ];then
----- do something -----
fi
done
May I know why do we need to have this check in if and what is it doing ?
That check is added to skip the header part. you can remove whole if statement by modifying awk statement to skip first line. To find out what header is run ps -eaf |head -n 1 .
for x in $(ps -ef | awk 'NR>1{ print $2 }')
do
--------Do something with $x---------
done
If you run ps -ef you will notice, that it will print a header:
UID PID PPID TTY STIME COMMAND
[...]
the check skips the header.
ps -ef | awk '{ print $2 }' outputs' as below; the first line is PID, so if statetement is used exclude PID line;
user#host:/tmp$ ps -ef | awk '{ print $2 }' | head
PID
1
2
3
5
7
8
9
10
you can also use this without if;
#!/bin/bash
for x in `ps -ef | awk '{ print $2 }' | grep -v PID`
do
#----- do something -----
echo $x
done

How to escape grep and awk within pipe in an alias?

I want to create an alias for an long command. But I'm not able to escape it correct, I guess it's a problem with the pipes.
My original command
ps aux | grep gimp | awk '{ print $2 '\011' $11 }' | grep -v 'grep'
My attempt for an alias
alias psa="ps aux | grep $1 | awk '{ print \$2 \"\011\" \$11 }' | grep -v 'grep'"
But I get an error that grep can not open file foo (when I do psa foo)
When I remove the last part | grep -v 'grep' then awkthrows the same error.
I prefer an alias before an shell script.
You need to use a function if you want to to insert arguments:
psa() {
ps aux | grep "$1" | awk '{print $2 "\t" $11 }' | grep -v grep
}
You can avoid all the escaping by using a function for this:
myps() {
ps aux | grep gimp | awk '{ print $2 "\011" $11 }' | grep -v 'grep'
}

Resources