Capture pid of a process started from a terminal with its unique command line - linux

I'm trying to get the process id of multiple processes run from a multiple tmux windows. Each processes started have their unique command line. I think only the command line is unique as there can be multiple processes with same name. what i did currently is
process_pid=$(ps --no-headers aux | grep "${process_cmd_line}" | grep -v grep | awk '{print $2}' | tr '\n' '')
This works for me. But i want to know if this is the correct approach to do this. I know there are output format specifiers. Any example to do the same with the format specifier or an improvement over the code above?

Related

kill multiple process at once works only manually not from inside script

I'm trying to kill multiple process at the same time.
Im using this simple for loop to kill the process by PID number.
for i in $(ps -ejH | grep omn_bdxtrc|awk '{print $1}'); do kill ${i}; done
The loop works fine if I enter it manually in the terminal.
but if I want to us it from inside an file (*.sh) it returns this output.
/functions.sh: line 231: kill: 25211
25698
27930
8477
5018
16383
13488
2403
10963 18796: arguments must be process or job IDs
have tried multiple ways that works manually, but not from the file.
Any ideas why this is happening?
Thanks in advance.
It looks like the PIDs are being passed as a single argument delimited by line breaks, which kill does not seem to like.
I would simplify the approach by removing the loop completely and just passing the PIDs to kill via xargs:
ps -ejH | grep omn_bdxtrc | awk '{print $1}' | xargs kill
Alternatively (if you don't have or don't want to use xargs for some reason), you can keep your current loop and just sanitize the output from awk by changing all possible line breaks to spaces using tr:
for i in $(ps -ejH | grep omn_bdxtrc | awk '{print $1}' | tr '\n' ' '); do kill ${i}; done
But this is not that elegant.
Probably the most elegant solution would be to use killall, assuming you know the exact name of the process:
killall omn_bdxtrc
Or if you don't know the exact name and need to match a part of it:
killall --regexp '.*omn_bdxtrc.*'

Show not logged users processes linux bash script

I am doing a bash script and i am essaying to show not logged users processes,which are typically daemon processes, for this,in the exercise, they recommend me:
To process the command line, we will use the cut command, which allows
selecting the different columns of the list through a filter.
I used:
ps -A | grep -v w
ps -A | grep -v who
ps -A | grep -v $USER
but trying all these options all the processes of all users are printed in the output file, and I only want the processes of users who are not logged.
I appreciate your help
Thank you.
grep -v w will remove lines matching the regular expression w (which is simply anything which contains the string w). To run the command w you have to say so; but as hinted in the instructions, you will also need to use cut to post-process the output.
So as not to give the answer away completely, here's rough pseudocode.
w | cut something >tempfile
ps -A | grep -Fvf tempfile
It would be nice if you could pass the post-processed results of w in a pipe, but standard input is already tied to ps -A. If you have a shell which supports process substitution, you can use that.
ps -A | grep -Fvf <(w | cut something)
Unfortunately, the output from w is not properly machine-readable -- you will properly want to cut out the header line(s), too. (On my machine, there are two header lines. Yours might differ.) You'll probably learn a bit of Awk later on in the course, but until then, maybe something like
ps -A | grep -Fvf <(w | tail -n +3 | cut something)
This still doesn't completely handle all possible situations. What if someone's account name is grep?

grep a variable containing special characters

i'm new to bash scripting and i have to determine if a process is running in a linux environment.
Actually i use the follow command to do the job:
#ps -ef | awk '{print substr($0, index($0,$8))}' | grep -v grep | grep -w -F $PROCESSNAME
where
awk '{print substr($0, index($0,$8))}'
allow me to ignore UID PID PPID C STIME TTY TIME fields and
grep -v grep
allow me to ignore the row that contains the command itself. So at this point i have a list of all processes running on the system.
Finally:
grep -w -F $PROCESSNAME
read a variable which contains the name of the process that i want to check.
For what i understand the full command should return only the row that has the exact value of $PROCESSNAME
Actually this doesn't works correctly for processes that follow the pattern "[processname]", and probably also for other patterns.
For example to simplify, if i have a running process named "[vmmemctl]" and i run:
#ps -ef | grep -v grep | grep -w -F "vmmemctl]"
it actually returns a result:
#root 615 2 0 Feb26 ? 00:01:00 [vmmemctl]
but the actual process name in the command is different from the process name in the result.
What is the correct command that doesn't have this behavior?
Thank you
awk to the rescue!
ps -ef | awk '$8=="[command]"{NF=8;print}'
or
ps -ef | awk -v c="vmmemctl]" '$8==c{NF=8;print}'
note that this is for an exact match not pattern.
since this is an exact match the command can have spaces and other special chars in it (it's not pattern match but string equality). Using your variable name it will look like this
ps -ef | awk -v c="$PROCESSNAME" '$8==c{NF=8;print}'

Get pid of last started instance of a certain process

I have several instances of a certain process running and I want to determine the process id of the one that has been started last.
So far I came to this code:
ps -aef | grep myProcess | grep -v grep | awk -F" " '{print $2}' |
while read line; do
echo $line
done
This gets me all process ids of myProcess. Somehow I need to compare now the running times of this pids and find out the one with the smallest running time. But I don't know how to do that...
An easier way would be to use pgrep with its -n, --newest switch.
Select only the newest (most recently started) of the matching
processes.
Alternatively, if you don't want to use pgrep, you can use ps and sort by start time:
ps -ef kbsdstart
Use pgrep. It has a -n (newest) option for that. So just try
pgrep -n myProcess

How to determine the exact character of a whitespace in linux?

I'm trying to get the PID field of ps -aux. I know I can achieve this using ps -aux | awk '{print $2}', but as practice wanted to see if I can do the same using the cut command. My idea is to specify a delimiter and chose the second field like this:
ps -aux | cut -d[delimiter] -f2
Using space as a delimiter (' ') did not work, neither did tab (\t).
In general, how do I find out the exact character of a white-space in linux?
To identify otherwise unprintable or similar-looking characters (like whitespace), pipe output to a tool like xxd or od -c. For example, this outputs both the hex values of each character as well as the text for easy lookup:
ps -aux | xxd -g 1 # -g 1 outputs each character individually
However I think your issue is that ps -aux uses multiple spaces between the fields; cut does not handle multiple consecutive delimiters, so it prints whatever's between the first and second space, i.e. nothing.
If you really want to use cut you have to remove both leading spaces and duplicate spaces:
ps -aux | sed 's/^ *//;s/ */ /g' | cut -d' ' -f2
cut doesn't support multi-chars as delimit.
There are multiple whitespace between fields, if you really want to use cut:
ps aux | sed 's/ */ /g' | cut -d ' ' -f 2
To get the PID of a ps command you can do this:
ps -aux | cut -c10-15
For information: the u that you use in ps aux means, according to man ps:
u Display user-oriented format
So you're explicitly asking for a human readable output and then you parse it with some tool? That's not very appropriate (to say the least). If you need to format the output of ps, please use the -o (or --format) option, if your version of ps accepts it. Hence:
ps ax -o pid
will be much better.

Resources