How to find the command line of a process only if the process is from current user - perl

I have the following situation:
A perl script read a file where a application wrote it's pid, and tries to kill it.
But the problem is that I don't want to kill another process so I check if current process with the recorded PID has the same command line. If so, the application could be killed.
The following blues script find out the cmdline:
$PIDCMDLINE = `ps -p $PID -o cmd`;
The problem is that if another instance for another user is up, maybe on the same sid, it would be killed because it will return a valid command line, and I don't want that behaviour.
How can I restrict ps -p to search only current users processes (no, simple ps doesn't count, because -p nullify the default effect of ps)
Thank you!

You can use the following to check both command and user for the certain PID:
ps -p <PID> -o user,cmd --columns 1000 | grep `whoami`
Adding a 'grep' according to the comment.

May be a little awkward, but what about this:
$PIDCMDLINE = ps -p $PID -o user,command | grep `whoami` | awk '{ print $2 }'

Related

How do I automate killing a job in cron? [duplicate]

This question already has answers here:
Find and kill a process in one line using bash and regex
(30 answers)
Closed 1 year ago.
Sometimes when I try to start Firefox it says "a Firefox process is already running". So I have to do this:
jeremy#jeremy-desktop:~$ ps aux | grep firefox
jeremy 7451 25.0 27.4 170536 65680 ? Sl 22:39 1:18 /usr/lib/firefox-3.0.1/firefox
jeremy 7578 0.0 0.3 3004 768 pts/0 S+ 22:44 0:00 grep firefox
jeremy#jeremy-desktop:~$ kill 7451
What I'd like is a command that would do all that for me. It would take an input string and grep for it (or whatever) in the list of processes, and would kill all the processes in the output:
jeremy#jeremy-desktop:~$ killbyname firefox
I tried doing it in PHP but exec('ps aux') seems to only show processes that have been executed with exec() in the PHP script itself (so the only process it shows is itself.)
pkill firefox
More information: http://linux.about.com/library/cmd/blcmdl1_pkill.htm
Also possible to use:
pkill -f "Process name"
For me, it worked up perfectly. It was what I have been looking for.
pkill doesn't work with name without the flag.
When -f is set, the full command line is used for pattern matching.
You can kill processes by name with killall <name>
killall sends a signal to all
processes running any of the specified
commands. If no signal name is
specified, SIGTERM is sent.
Signals can be specified either by
name (e.g. -HUP or -SIGHUP ) or by number (e.g.
-1) or by option -s.
If the command name is not regular
expression (option -r) and contains a
slash (/), processes executing that
particular file will be selected for
killing, independent of their name.
But if you don't see the process with ps aux, you probably won't have the right to kill it ...
A bit longer alternative:
kill `pidof firefox`
The easiest way to do is first check you are getting right process IDs with:
pgrep -f [part_of_a_command]
If the result is as expected. Go with:
pkill -f [part_of_a_command]
If processes get stuck and are unable to accomplish the request you can use kill.
kill -9 $(pgrep -f [part_of_a_command])
If you want to be on the safe side and only terminate processes that you initially started add -u along with your username
pkill -f [part_of_a_command] -u [username]
Kill all processes having snippet in startup path. You can kill all apps started from some directory by for putting /directory/ as a snippet. This is quite usefull when you start several components for the same application from the same app directory.
ps ax | grep <snippet> | grep -v grep | awk '{print $1}' | xargs kill
* I would prefer pgrep if available
Strange, but I haven't seen the solution like this:
kill -9 `pidof firefox`
it can also kill multiple processes (multiple pids) like:
kill -9 `pgrep firefox`
I prefer pidof since it has single line output:
> pgrep firefox
6316
6565
> pidof firefox
6565 6316
Using killall command:
killall processname
Use -9 or -KILL to forcefully kill the program (the options are similar to the kill command).
On Mac I could not find the pgrep and pkill neither was killall working so wrote a simple one liner script:-
export pid=`ps | grep process_name | awk 'NR==1{print $1}' | cut -d' ' -f1`;kill $pid
If there's an easier way of doing this then please share.
To kill with grep:
kill -9 `pgrep myprocess`
more correct would be:
export pid=`ps aux | grep process_name | awk 'NR==1{print $2}' | cut -d' ' -f1`;kill -9 $pid
I normally use the killall command.
Check this link for details of this command.
I was asking myself the same question but the problem with the current answers is that they don't safe check the processes to be killed so... it could lead to terrible mistakes :)... especially if several processes matches the pattern.
As a disclaimer, I'm not a sh pro and there is certainly room for improvement.
So I wrote a little sh script :
#!/bin/sh
killables=$(ps aux | grep $1 | grep -v mykill | grep -v grep)
if [ ! "${killables}" = "" ]
then
echo "You are going to kill some process:"
echo "${killables}"
else
echo "No process with the pattern $1 found."
return
fi
echo -n "Is it ok?(Y/N)"
read input
if [ "$input" = "Y" ]
then
for pid in $(echo "${killables}" | awk '{print $2}')
do
echo killing $pid "..."
kill $pid
echo $pid killed
done
fi
kill -9 $(ps aux | grep -e myprocessname| awk '{ print $2 }')
If you run GNOME, you can use the system monitor (System->Administration->System Monitor) to kill processes as you would under Windows. KDE will have something similar.
The default kill command accepts command names as an alternative to PID. See kill (1). An often occurring trouble is that bash provides its own kill which accepts job numbers, like kill %1, but not command names. This hinders the default command. If the former functionality is more useful to you than the latter, you can disable the bash version by calling
enable -n kill
For more info see kill and enable entries in bash (1).
ps aux | grep processname | cut -d' ' -f7 | xargs kill -9 $
awk oneliner, which parses the header of ps output, so you don't need to care about column numbers (but column names). Support regex. For example, to kill all processes, which executable name (without path) contains word "firefox" try
ps -fe | awk 'NR==1{for (i=1; i<=NF; i++) {if ($i=="COMMAND") Ncmd=i; else if ($i=="PID") Npid=i} if (!Ncmd || !Npid) {print "wrong or no header" > "/dev/stderr"; exit} }$Ncmd~"/"name"$"{print "killing "$Ncmd" with PID " $Npid; system("kill "$Npid)}' name=.*firefox.*

Check number of active meetings in Big Blue Button from command line

I want to check how many active meetings there are on the BBB server at any one time from the command line. I have tried
$ bbb-conf --network
but not getting anywhere. I have also checked the number of active connections to port 80 and 443
$ netstat -anp | grep :443 | grep ESTABLISHED | wc -l
but I'm not sure if I can trust that figure.
I know I can use the isMeetingRunning call from the API but I'm just looking for command line.
Any ideas would be appreciated
The following bash script, which can be run from command line on the same machine as the BigBlueButton server, will process the response to the BBB API getMeetings call.
#!/bin/bash
APICallName="getMeetings"
APIQueryString=""
X=$( bbb-conf --secret | fgrep URL: )
APIEndPoint=${X##* }
Y=$( bbb-conf --secret | fgrep Secret: )
Secret=${Y##* }
S=$APICallName$APIQueryString$Secret
Checksum=$( echo -n $S | sha1sum | cut -f 1 -d ' ' )
if [[ "$APIQueryString" == "" ]]
then
URL="${APIEndPoint}api/$APICallName?checksum=$Checksum"
else
URL="${APIEndPoint}api/$APICallName?$APIQueryString&checksum=$Checksum"
fi
wget -q -O - "$URL" | grep -o '<meetingID>' | wc -w
Tested on a live BBB machine.
Note:
The APICallName and APIQueryString can be modified to provide interface to other BBB API calls. See https://docs.bigbluebutton.org/dev/api.html
The command-line sha1sum will output a different result if a newline is appended to its input. This is the reason echo -n is used instead of echo.
In the last line, the script processes the XML output from the API call in a very naïve way, simply counting the number of occurences of the <meetingID> tag. More elaborate processing would probably require parsing the XML.

using here document and pipeline of sh at the same time

I'm using here document of sh to run some commands. now I want to parse the output of those commands using awk. However, everytime I execute it, I get the output of the command append with something like this "% No such child process"
This is how my script looks like.
#!/bin/sh
com = "sudo -u username /path/of/file -l"
$com <<EOF | awk '{print $0}'
Commands.
.
.
.
EOF
How am I going to use heredoc and pipeline without appending that unwanted string?
Thanks
Your variable assignment is wrong in a couple of ways. First, you aren't actually assigning a variable; you're trying to run a command named com whose arguments are = and a string "sudo ...". Spaces must not be used on either side of the =:
com="sudo ..."
Second, command lines should not be stored in a variable; the shell's parser can only make that work they way you intend for very simple commands. Type the command out in full, or use a shell function.
com () {
sudo -u username /path/to/file -l
}
com <<EOF | awk '{print $0}'
...
EOF
There's no problem, check :
$ cat <<EOF | awk '{print $1}'
a b c
1 2 3
EOF
a
1

Command not running fron cron

I have a perl script which runs successfully from the root cron on my redhat server.
However, I have added a command to the perl script to execute an ldapsearch and when running the perl script from the command line it works perfectly, yet running from cron, the ldapseach command does not work.
I've the the full path to the ldapsearch executable and I have tried using both system and exec before the ldapsearch command, but no good.
The line in the perl code does the ldap search for container room, greps the specific line in the results, then parses the data and cuts the 1st two characters of the results. The code is:
$userRoom = `exec /usr/local/bin/ldapsearch -h myldap.domain.com '(cn=$user)' room | /bin/grep -i room | /bin/grep -iv internal | /bin/cut -d'=' -f2 | /bin/cut -c 1-2`;
I'm assuming it's an evironment or permissions thing. I just can't find the right answer.
Any suggestions greatly appreciated.

Get current playing file in MPlayer slave mode

Problem: I can't find any way to reliably get the current playing file in an MPlayer playlist.
Here is how far I have gotten. This working ash script monitors a text file with the path to the current playlist. When I update the file, the script closes the old instance of MPlayer and opens a new one with the new playlist:
# POLL PLAYLIST FILE FOR CHANGES
CURRENTPLAYLISTPATH=/home/tc/currentplaylist
INFIFO=/tmp/mplayer-in
CURRENTPLAYLIST="NEVERMATCHAPLAYLIST"
FIRSTRUN=1
while [ 1 ];
do
# CHECK FOR NEW PLAYLIST
NEWPLAYLIST=$(head -n 1 $CURRENTPLAYLISTPATH)
if [[ "$NEWPLAYLIST" != "$CURRENTPLAYLIST" ]]; then
if [ "$FIRSTRUN" == 0 ]; then
echo "quit" > "$INFIFO"
fi
# CREATE NAMED PIPE, IF NEEDED
trap "rm -f $INFIFO" EXIT
if [ ! -p $INFIFO ]; then
mkfifo $INFIFO
fi
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=$INFIFO -quiet -msglevel all=0 -identify | tee -a /home/tc/mplayer.log &
CURRENTPLAYLIST=$NEWPLAYLIST
FIRSTRUN=0
fi
sleep 5;
done
My original plan was just to use the "-identify" flag and parse the log file. This actually works really well up until I need to truncate the log file to keep it from getting too large. As soon as my truncating script is run, MPlayer stops writing to the log file:
FILENAME=/home/tc/mplayer.log
MAXCOUNT=100
if [ -f "$FILENAME" ]; then
LINECOUNT=`wc -l "$FILENAME" | awk '{print $1}'`
if [ "$LINECOUNT" -gt "$MAXCOUNT" ]; then
REMOVECOUNT=`expr $LINECOUNT - $MAXCOUNT`
sed -i 1,"$REMOVECOUNT"d "$FILENAME"
fi
fi
I have searched and searched but have been unable to find any other way of getting the current playing file that works.
I have tried piping the output to another named pipe and then monitoring it, but only works for a few seconds, then MPlayer completely freezes.
I have also tried using bash (instead of ash) and piping the output to a function like the following, but get the same freezing problem:
function parseOutput()
{
while read LINE
do
echo "get_file_name" > /tmp/mplayer-in
if [[ "$LINE" == *ANS_FILENAME* ]]
then
echo ${LINE##ANS_FILENAME=} > "$CURRENTFILEPATH"
fi
sleep 1
done
}
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=/tmp/mplayer-in -quiet | parseOutput &
I suspect I am missing something very obvious here, so any help, ideas, points in the right direction would be greatly appreciated.
fodder
Alright then, so I'll post mine too.
Give this one a try (assuming there is only one instance running, like on fodder's machine):
basename "$(readlink /proc/$(pidof mplayer)/fd/* | grep -v '\(/dev/\|pipe:\|socket:\)')"
This is probably the safer way, since the file descriptors might not always be in the same order on all systems.
However, this can be shortened, with a little risk:
basename "$(readlink /proc/$(pidof mplayer)/fd/*)" | head -1
You might probably like to install this, too:
http://mplayer-tools.sourceforge.net/
Well, I gave up on getting the track from MPlayer itself.
My 'solution' is probably too hackish, but works for my needs since I know my machine will only ever have one instance of MPlayer running:
lsof -p $(pidof mplayer) | grep -o "/path/to/my/assets/.*"
If anyone has a better option I'm certainly still interested in doing this the right way, I just couldn't make any of the methods work.
fodder
You can use the run command.
Put this in ~/.mplayer/input.conf:
DEL run "echo ${filename} ${stream_pos} >> /home/knarf/out"
Now if you press the delete key while playing a file it will do what you expect i.e. append the current file playing and the position in the stream to the ~/out file. You can replace echo with your program.
See slave mod docs for more info (Ctrl-F somevar).
About getting properties from MPlayer
I have used a non-elegant solution, but it is working for me.
stdbuf -oL mplayer --slave --input=file=$FIFO awesome_awesome.mp3 |
{
while IFS= read -r line
do
if [[ "${line}" == ANS_* ]]; then
echo "${line#*=}" > ${line%=*} # echo property_value > property_name
fi
done
} &
mplayer_pid=&!
read filename < ./ANS_FILENAME
read timeLength < ./ANS_LENGTH
echo ($timeLength) $filename
and so on..
It is in another proccess, that's why I've used files to bring properties
'stdbuf' is for not to miss anything
I started putting together a bash library to handle tasks like this. Basically, you can accomplish this by dumping the mplayer output to a file. Then you grep that dump for "Playing " and take the last result with tail. This should give you the name of the file that's currently playing or that last finished playing.
Take a look at my bash code. You'll want to modify the playMediaFile function to your needs, but the getMediaFileName function should do exactly what you're asking. You'll find the code on my github.