How do I execute the kill -9 in this perl one liner? I have gotten down to where I have the pids listed and can print it out to a file, like so:
ps -ef | grep -v grep |grep /back/mysql | perl -lane '{print "kill -9 $F[1]"}'
Have you considered pkill or pgrep?
pkill /back/mysql
or
pgrep /back/mysql | xargs kill -9
OK, heavily edited from my original answer.
First, the straightforward answer:
ps -ef | grep -v grep |grep /back/mysql | perl -lane 'kill 9, $F[1]'
Done.
But grep | grep | perl is kind of a silly way to do that. My initial reaction is "Why do you need Perl?" I would normally do it with awk | kill, saving Perl for more complicated problems that justify the extra typing:
ps -ef | awk '/\/back\/mysql/ {print $2}' | xargs kill -9
(Note that the awk won't find itself because the string "\/back\/mysql" doesn't match the pattern /\/back\/mysql/)
You can of course use Perl in place of awk:
ps -ef | perl -lane 'print $F[1] if /\/back\/mysql/' | xargs kill -9
(I deliberately used leaning toothpicks instead of a different delimiter so the process wouldn't find itself, as in the awk case.)
The question then switches from "Why do you need perl?" to "Why do you need grep/awk/kill?":
ps -ef | perl -lane 'kill 9, $F[1] if /\/back\/mysql/'
Let's use a more appropriate ps command, for starters.
ps -e -o pid,cmd --no-headers |
perl -lane'kill(KILL => $F[0]) if $F[1] eq "/back/mysql";'
ps -ef | grep -v grep |grep /back/mysql | perl -lane 'kill(9, $F[1])'
The kill function is available in Perl.
You could omit the two grep commands too:
ps -ef | perl -lane 'kill(9, $F[1]) if m%/back/mysql\b%'
(untested)
Why aren't you using even more Perl?
ps -ef | perl -ane 'kill 9,$F[1] if m{/back/mysql}'
Related
Just a basic question about grep command line. I found the way how to know that the service is running in process by using this command line:
ps -ef |grep -v grep | grep mongodb
I'm confused about the second grep:
|grep -v grep |
Why I need to use the "grep" after " -v " ???
What is the different between that command and this command ?
ps -ef |grep mongodb
Thank you!
When you grep "mongodb" through command line, your command also contains the word "mongodb" . So you will get two results. Which is flawed result. grep -v is to remove the grep command typed by user.
sh-4.1$ ps -ef |grep -v grep | grep mongodb
ps 17308 30074 0 06:05 pts/300 00:00:00 sh mongodb
vs
sh-4.1$ ps -ef |grep mongodb
ps 17308 30074 0 06:05 pts/300 00:00:00 sh mongodb
ps 17456 30074 0 06:05 pts/300 00:00:00 grep mongodb #<<<This also contains mongodb word. Hence result is flawed.
The -v option tells grep not to let through anything matching the pattern, in this case lines that contain the string "grep".
So if you omit the grep -v grep
your grep process itself would also be displayed in the output after the second command in the pipe (and also after the third, as the grep process itself contains the word "mongodb").
thanks in advance for the help.
I have the following line that does work on linux.
myfile (extract)
active_instance_count=
aq_tm_processes=1
archive_lag_target=0
audit_file_dest=?/rdbms/audit
audit_sys_operations=FALSE
audit_trail=NONE
background_core_dump=partial
background_dump_dest=/home1/oracle/app/oracle/admin/iopecom/bdump
...
cat myfile |sed -r 's/ {1,}//g'|sed -r 's/\t*//g' |grep -v "^#"|sed -s "/^$/d" |sed =|sed 'N;s/\n/\t/'|sed -r "s/#.*//g" | sed "s/\t/;/g"|sed "s/\t/;/g"|sed -e "s,',\o042,g"
The result will be:
1;O7_DICTIONARY_ACCESSIBILITY=TRUE
2;active_instance_count=
3;aq_tm_processes=1
4;archive_lag_target=0
5;audit_file_dest=?/rdbms/audit
6;audit_sys_operations=FALSE
7;audit_trail=NONE
8;background_core_dump=partial
9;background_dump_dest=/home1/oracle/app/oracle/admin/iopecom/bdump
But, I can't figure out, how to perform the same command on AIX server.
Help is very welcome.
Regards.
Antonio.
Unless you have a compelling reason to use sed, you could use alternate tools:
awk -v OFS=';' '{print NR,$0}' filename
would produce the desired output.
You could also use perl:
perl -ne 'print "$.;$_"' filename
It appears that your sed expression would skip lines beginning with a #. As such, you could say:
perl -ne '$,=";"; !/^#/ && print ++$i,$_' filename
or something like:
grep -v '^#' filename | awk ...
reformatting your pipeline:
cat myfile |
sed -r 's/ {1,}//g' | # strip all spaces (1)
sed -r 's/\t*//g' | # strip all tabs (2)
grep -v "^#" | # delete all lines beginning `#` (3)
sed -s "/^$/d" | # delete all empty lines (4)
sed = | # interleave with line numbers (5)
sed 'N;s/\n/\t/' | # join line number and line with `\t` (6)
sed -r "s/#.*//g" | # strip all `#` comments (7)
sed "s/\t/;/g" | # replace all tabs with `;` (8)
sed "s/\t/;/g" | # do it again (9)
sed -e "s,',\o042,g" # replace all ' with " (10)
Boiling that down and using cat -n to provide the line numbers up front gets:
cat -n myfile |
sed "$(print 's/\t/;/')
$(print 's/[ \t]*//g')
s/#.*//g
/^$/d
s/'/\"/g"
which behaves identically unless I'm misreading the aix docs. The $(...) construction is command substitution, it runs that command and substitutes its output. print would be printf on linux.
i want to grep pattern from a large file. But using grep it is very slow and pattern to be grep is also case insensitive. So , i read that perl is faster for file reading. Someone please tel me a way to do it in perl.
Thanks.
cat File1.txt File2.txt | grep -in "exception" | grep -v "pattern"
In perl:
perl -ne 'print "$.:$_" if /exception/i and !/pattern/' File1.txt File2.txt
or without cat:
grep -in "exception" File1.txt File2.txt | grep -v "pattern"
I am doubtful that Perl would give you a performance advantage in this area. The grep utility is a pre-compiled binary written in C; Perl is an interpreted language and bears an extra performance overhead which e.g. GNU grep does not. If grep is slow the bottleneck is most likely the file being loaded from disk into main memory. How big is the file?
FYI, grep has flags which enable case-insensitive matching and Perl-style regex syntax.
% grep -i 'abc' <file> # Matches abc, ABC, aBc, etc.
% grep -i 'ab\|cd' <file> # Matches ab or cd
% grep -P 'ab|cd' <file> # Matches ab or cd
An equivalent Perl program is:
# grep.pl
$pat = shift;
while(<>) { if(/$pat/i) { print; } }
which can be invoked as
perl grep.pl abc file1.txt file2.txt ...
My advice, stick with grep.
grep -i 'pattern' file->perl -lne 'print if(/pattern/i)' file
grep -vi 'pattern' file->perl -lne 'print unless(/pattern/i)' file
If you want everything with line numebrs as well, the replace the print
with print "$. $_" in the above commands
When i execute the below command in command prompt it works fine. but when i include the same in perl script, it shows the whole process name.
ps -ef | grep truecontrol | awk '{print$2}'
returns
4567
3456
When I execute it throught perl, it shows the whole process details. I want to assign it to a variable array and work on it. Let me know how to do it?
my $process_chk_command = `ps -ef | grep truecontrol | awk '{print$2}'`;
print($process_chk_command);
root 9902 9890 0 05:50 ? 00:00:03 /opt/abc/jre/bin/java -DTCFTP=1 -d64 -Xms16m -Xmx64m -Djava.library.path=/opt/abc/server/ext/wrapper/lib -cla
perl's backticks and qx// interpolate variables, so when you write:
my $process_chk_command = `ps -ef | grep truecontrol | awk '{print $2}'`;
perl interpolates the special variable $2. In your case, $2 is not set, and thus expands to the empty string, so the awk command is simply {print}.
You could escape the dollar sign (`ps ... | awk '{print \$2}'`) to avoid this.
(As an aside, I'd recommend grep [t]ruecontrol to prevent grep from matching its own process table entry, or that of its parent shell which constructs the pipeline. sh aficionados with a POSIX bent might additionally suggest `ps -eo pid,comm,args | awk '/[t]ruecontrol/{print \$1}'`.)
Try using pgrep
my $process_chk_command = `pgrep truecontrol`;
my $process_chk_command = `ps -ef | grep truecontrol`;
my (undef,$pid) = split(' ', $process_chk_command, -1);
ps, there's a perl utility that converts awk scripts to perl: a2p
True to Perl's motto, another way:
my $pcc=`killall -s truecontrol`;
my (undef,undef,$pid)=split(' ',$pcc);
print $pid;
I have a script2:
# This is script2 that is called by script1.
CURRENT_TOMCAT_PROCESS=`ps -ef | grep java | grep $TOMCAT_USER | grep -v grep | awk '{print $2}'`
echo "---> $CURRENT_TOMCAT_PROCESS"
and I call script2 in script1:
ssh $user#$server 'bash -s' < script2
It works fine. But I'm having trouble make the backtick work in a HERE document:
ssh $user#$server 'bash -s' <<EOF
CURRENT_TOMCAT_PROCESS=`ps -ef | grep java | grep $TOMCAT_USER | grep -v grep | awk '{print \$2}'`
echo "---> $CURRENT_TOMCAT_PROCESS"
EOF
(If I don't assign it to a variable and just print it out it works fine, but when I try to assign it to CURRENT_TOMCAT_PROCESS variable using backticks, it doesn't work.)
How can I make this work?
Thanks,
===============================================================================
I could make it work the following way. There are lots of escaping involved:
ssh $user#$server 'bash -s' <<EOF
CURRENT_TOMCAT_PROCESS="\`ps -ef | grep java | grep $TOMCAT_USER | grep -v grep | awk '{print \$2}'\`"
echo "---> \$CURRENT_TOMCAT_PROCESS"
EFO
I think it is reasonable to escape, because you want to transfer the '$' to remote site. You seems make a typo on your last result. I tried to type here again
TOMCATE_USER=foo
ssh $user#$server 'bash -s' <<EOF
CURRENT_TOMCAT_PROCESS="\`ps -ef | grep java | grep $TOMCAT_USER | grep -v grep | awk '{print \$2}'\`"
echo "---> \$CURRENT_TOMCAT_PROCESS"
EOF