How to stop grep after matching - regex

In Windows, I would have done a search for finding a folders name using findsr Similarly, I want to get a specific folder using grep
In windows, I'm using svnlook tree -t [repos_path] | findstr (13\.9\.[0-9]+\/)
In Ec2 Maiche (Linux) svnlook tree /var/www/svn/ILS | grep -Eo '(13\.9\.[0-9]+\/)'
and I got the repos that I need
13.9.4/
13.9.5/
13.9.6/
13.9.7/
my problem is the grep line in Linux doesn't want to stop (exit) it's still running.
how could I stop it after matching?

You can specify the -m: maximal number of counts. After the specified number of matching lines, grep will stop.

After ^Z the svnlook is paused. You kan kill (^C) the program, send it to the background (bg) or continue (fg).
When you want to interrupt you can use ^C or start the grep with a -m option.

Related

Unable to do a word count of a file through ssh in unix shell scripting

I need to go another server and perform a word count. Based on the count variable I will perform a if else logic.
However i am unable to do a word count and further unable to compare the variable value in if condition.
Error:
wc: cannot open the file v.txt
Script:
#!/bin/bash
ssh u1#s1 "cd ~/path1/ | fgrep-f abc.csv xyz.csv > par.csv | a=$(wc -l par.csv)| if ["$a" == "0"];
then echo "success"
fi"
First, although the wc program is named for 'word count', wc -l actually counts lines not words. I assume that is what you want even though it isn't what you said.
A shell pipline one | two | three runs things in parallel with (only) their stdout and stdin connected; thus your command runs one subshell that changes directory to ~/path1 and immediately exits with no effect on anything else, and at the same time tries to run fgrep-f (see below) in a different subshell which has not changed the directory and thus probably can't find any file, and in a third subshell does the assignment a= (see below) which also immediately exits so it cannot be used for anything.
You want to do things sequentially:
ssh u#h 'cd path1; fgrep -f abc.csv xyz.csv >par.csv; a=$(wc -l par.csv); if [ "$a" == "0" ] ...'
# you _might_ want to use && instead of ; so that if one command fails
# the subsequent ones aren't attempted (and possibly go further wrong)
Note several other important changes I made:
the command you give ssh to send the remote must be in singlequotes ' not doublequotes " if it contains any dollar as yours does (or backtick); with " the $(wc ...) is done in the local shell before sending the command to the remote
you don't need ~/ in ~/path1 because ssh (or really sshd) always starts in your home directory
there is no common command or program fgrep-f; I assume you meant the program fgrep with the flag -f, which must be separated by a space. Also fgrep although traditional is not standard (POSIX); grep -F is preferred
you must have a space after [ and before ]
However, this won't do what you probably want. The value of $a will be something like 0 par.csv or 1 par.csv or 999 par.csv; it will never equal 0 so your "success" branch will never happen. In addition there's no need to do these in separate commands: if your actual goal is to check that there are no occurrences in xyz.csv of the (exact/non-regexp) strings in abc.csv both in path1, you can just do
ssh u#h 'if ! grep -qFf path1/abc.csv path1/xyz.csv; then echo success; fi'
# _this_ case would work with " instead of ' but easier to be consistent
grep (always) sets its exit status to indicate whether it found anything or not; flag -q tells it not to output any matches. So grep -q ... just sets the status to true if it matched and false otherwise; using ! inverts this so that if grep does not match anything, the then clause is executed.
If you want the line count for something else as well, you can do it with a pipe
'a=$( fgrep -Ff path1/abc.csv path1/xyz.csv | wc -l ); if [ $a == 0 ] ...'
Not only does this avoid the temp file, when the input to wc is stdin (here the pipe) and not a named file, it outputs only the number and no filename -- 999 rather than 999 par.csv -- thus making the comparison work right.

Disk Space Usage Profiling in Linux

I am running C++ program on Linux [Red Hat], This program creates temporary files on the Hard Disk to compute its result. I need to know how much space does this program use from the Disk while it is running. I could not able to change the source code to keep the files so I can subtract the size of the Program folder before and after producing the results. is there any profiling tool or command line that I can use to help me in this situation.
You can use du -h /path/todir before and after the program run from the terminal, I suppose.
du - estimate file space usage
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
If you need further options just take a look at man du
You may make use of stats maintained in /proc/[pid]/io .
From /proc man page :
This file contains I/O statistics for the process, for
example:
# cat /proc/3828/io
rchar: 323934931
wchar: 323929600
syscr: 632687
syscw: 632675
read_bytes: 0
write_bytes: 323932160
cancelled_write_bytes: 0
write_bytes: bytes written
Attempt to count the number of bytes which this process
caused to be sent to the storage layer.
You may write script something like ,
#!/bin/bash
c=0
echo $1
rm /tmp/writtenBytes.txt
psout=`ps aux | grep "$1" | grep -v $0 | grep -v grep `
while [[ "$psout" != "" ]]
do
pid=`echo $psout | awk '{print $2}'`
cat /proc/$pid/io | grep write | grep -v cancelled >> /tmp/writtenBytes.txt
psout=`ps aux | grep "$1" | grep -v $0 | grep -v grep`
echo $psout
sleep 1
done
Run this script as
bash -x getIO.sh "postgres: stats collector"
This script will create file /tmp/writtenBytes.txt, containing number of bytes written by processes named "postgres: stats collector"

So, what exactly is the deal with QSharedMemory on application crash?

When a Qt application that uses QSharedMemory crashes, some memory handles are left stuck in the system.
The "recommended" way to get rid of them is to
if(memory.attach(QSharedMemory::ReadWrite))
memory.detach();
bool created = memory.create(dataSize, QSharedMemory::ReadWrite);
In theory the above code should work like this:
We attach to a left over piece of sh...ared memory, detach from it, it detects that we are the last living user and gracefully goes down.
Except... that is not what happens in a lot of cases. What I actually see happening, a lot, is this:
// fails with memory.error() = SharedMemoryError::NotFound
memory.attach(QSharedMemory::ReadWrite);
// fails with "segment already exists" .. wait, what?! (see above)
bool created = memory.create(dataSize, QSharedMemory::ReadWrite);
The only somewhat working way I've found for me to work around this is to write a pid file on application startup containing the pid of the currently running app.
The next time the same app is run it picks up this file and does
//QProcess::make sure that PID is not reused by another app at the moment
//the output of the command below should be empty
ps -p $previouspid -o comm=
//QProcess::(runs this script, reads output)
ipcs -m -p | grep $user | grep $previouspid | sed "s/ / /g" | cut -f1 -d " "
//QProcess::(passes the result of the previous script to clean up stuff)
ipcrm -m $1
Now, I can see the problems with such approach myself, but it is the only thing that works
The question is: can someone explain to me what exactly is the deal with not so not existing memory in the first piece of code above and how to deal with it properly?

OSX bash scripting

I don't do much shell scripting but I want to essentially do this:
run the command "grunt check" about 30 times (the process takes 60 seconds).
Do a regex on the output of that command for "Some random error message. Failed." Where "Failed" is the thing I'm searching for but I want to capture the whole sentence.
Write the associated line to a file.
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 30 ]; do
command grunt check
// ERROR = regex(/\/Failed./)
// WRITE ERROR TO FILE
let COUNTER=COUNTER+1
done
for ((cr=0; cr<30; cr++))
do
grunt check | grep Failed
done > outfile.txt
counter=0
while [ $counter -lt 30 ]; do
grunt check | grep Failed
let counter=counter+1
done > some file
The above uses a pipeline to capture the output of the grunt command and sent it to grep. grep searches through the output and prints any lines that contain the word Failed. Any such lines are then sent to a file named somefile.
As a minor point, I have converted COUNTER to lower case. This is because the system uses upper case environment variables. If you make a practice of using lower case ones then you won't accidentally overwrite one. (In this particular case, there is no system variable named COUNTER, so you are safe.)
Another method for counting to 30:
You might find this simpler:
for counter in {1..30}; do
grunt check | grep Failed
done > somefile
The {1..30} notation provides the numbers from one to thirty. It is a bash feature so don't try to use it on a bare-bones POSIX shell.
To get more context
If you would like to see more context around the error message, grep offers several options to help. To see both the line matching "Failed" and the line before, use -B:
for counter in {1..30}; do
grunt check | grep -B 1 Failed
done >somefile
Similarly, -A can be used to display lines after the match. -C will display lines both before and after the match.

How to kill process in c++, knowing only part of its name

Some time ago I needed to write c++ code to kill some process. In my main program I run large CAE-system package with system("...") with different filename strings on input. CAE-software creates many processes, that contain in process name string filename). Some of the CAE-processes worktime > max_time, than I need to shut them down:
//filename contains part of CAE-process name
string s="/bin/kill -9 `ps aux | grep "+filename+" | awk {'print $2'}`";
system(s.c_str());
The output was:
Usage:
kill pid ... Send SIGTERM to every process listed.
kill signal pid ... Send a signal to every process listed.
kill -s signal pid ... Send a signal to every process listed.
kill -l List all signal names.
kill -L List all signal names in a nice table.
kill -l signal Convert between signal numbers and names.
I tried to run with execvp, tried different ways running kill or pkill over bash script, calling system("name_of_script.sh"), where script contained kill -9 *filename* but the result was the same.
Using kill and /bin/kill gave the same output, bash -c kill... too.
Using kill from my system (Ubuntu Natty) gnome-terminal:
kill -9 `ps aux | grep filename | awk {'print $2'}`
shutdown all necessary processes! It works.
When using pkill, as I could understand, we need full process name to kill it, but I have only part of name.
I also tried to wrap computational process into a child thread using pthreads and stop it with pthread_cancel, but it doesn't work because of CAE-system process doesn't receive signals (I think, trapping them), the only way is SIGTERM.
Killing child-thread-"wrap" with pthread_kill also kills the parent (my main program).
I don't know CAE-process pids to call kill from signals.h
Closing main program do not stop CAE-processes (and the do not have -Z flag, so are they aren't my program process childs??)
How can I close CAE-processes, that run > MAXTIME from my main program?
The problem was that I was running main program via debugger (gdb) in QtCreator. Without QtCreator shell-script runs with arguments the right way, though arguments are passed correctly both ways.
Also I have to clear some CAE processes, that don't have filename in cmdline, but that are parents or children of this process.
In shell-script you can use:
cat /proc/"$P"/status | grep PPid | grep -o "[0-9]*"
where $P is a variable with pid of killed process.
Here are several methods to kill all child processes.
I'll write smth. similar in C++ that will scan /proc/xxxx/status till PPid= ppid_of_my main_program and cut that branch.
You don't have to open a shell to kill a process. Just use the "kill" function:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
http://linux.die.net/man/2/kill
To find a process to kill read the following directory:
/proc/####/cmdline
Where #### is the number of any running process id. So the code roughly would be to read the /proc directory and list out all the numerical directories, these are the current running processes, and you find the name of the command that spawned that process in the "cmdline" file in that directory. You can then use a regular expression, or a string comparison to identify processes to kill.
This should just work assuming filename isn't too much exotic or contains a regular expression pattern:
string s="pkill -9 -f "+filename";
system(s.c_str());
As a side note, -9 is a last resort signal, not something you should start with. I would thus recommend the less brutal:
string s="pkill -f "+filename"+";sleep 2; pkill -9 -f "+filename;
system(s.c_str());