pgrep program with hyphen in linux? - grep

how to pgrep a program contains hyphen? Considering case like bellow.
c source file name, program-contains-hypen.c:
#include <stdio.h>
int main(int argc, char *argv[])
{
getchar();
return 0;
}
then keep editing it with vim, and run the compiled program-contains-hypen in another terminal.
at this time, if I use pgrep program-contains-hypen, nothing got; if I use pgrep -f program-contains-hypen, two results got.
how to exactly get the pid of program program-contains-hypen?
ps:
$ pgrep --version
pgrep from procps-ng 3.3.10
update:
It's not the problem of hyphen but the length of command line.
see https://askubuntu.com/questions/361104/pgrep-pattern-length-limit.
thanks to #user5631389

I think you've answered your own question. pgrep -f is the correct way to do this. If you're getting two results, you have two running processes with that name. You can use pgrep -fa to see the whole command line. For example:
Without -f, you will only be able to use a certain number of characters according to https://askubuntu.com/questions/361104/pgrep-pattern-length-limit. For example:
$ pgrep unity-scope-loader
$ pgrep unity-scope-loade
$ pgrep unity-scope-load
$ pgrep unity-scope-loa
9489
$ pgrep -f unity-scope-loader
9489
$ pgrep -fa unity-scope-loader
9489 /usr/bin/unity-scope-loader applications/applications.scope applications/scopes.scope commands.scope
$ awk '$11~/unity-scope-loader/{print $2}' <(ps aux)
9489

Related

How to use grep to match the files?

I am trying to learn RegEx, but it is hard.
For example, i have 3 files:
$ ls
thisisnothing12.txt Thisisnothing12.txt thisisnothing.txt
I want to use ls to grep out only the 2 files with digits on it..
These are what i have tried, but they doesn't show even a single file.. why ? What's wrong with em ?
$ ls | grep "^[\w]+[\d]+\.[\w]{3}$"
$ ls | grep "^[a-zA-Z]+[0-9]+\.[a-zA-Z]{3}$"
Thx.
There are different regex flavors, see https://stackoverflow.com/a/66256100/7475450
You need to use PCRE if you want to use \d:
$ touch thisisnothing12.txt Thisisnothing12.txt thisisnothing.txt
$ ls
Thisisnothing12.txt thisisnothing.txt thisisnothing12.txt
$ ls | grep '\d' # '\d' does not work in POSIX Basic regex
$ ls | grep -P '\d' # use PCRE regex
Thisisnothing12.txt
thisisnothing12.txt
$
As you can see you can search for just the characters you are interested in.
You can narrow down, such as finding files that start with a number:
$ touch 2feet.txt
$ ls | grep -P '\d'
2feet.txt
Thisisnothing12.txt
thisisnothing12.txt
$ ls | grep -P '^\d'
2feet.txt
$
Learn more with this tutorial: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex
^[\w]+[\d]+\.[\w]{3}$
^[a-zA-Z]+[0-9]+\.[a-zA-Z]{3}$
Let's simplify a bit. They are both essentially the same thing, because [\w] is the same as \w which is [A-Za-z]. And the same for \d.
So we can simplify to
^\w+\d+\.\w{3}$
The issue is that ^ asserts the start of the string, and $ is the end. grep works on each line. And ls returns all results on one line. You can use ls -1 to get one file per line. You also need the -P flag for grep to work with \w and \d.
$ ls -1 | grep -P "^\w+\d+\.\w{3}$"
You can try different regexes here: https://regexr.com/5mujo

How to colorize logs for docker container

I have container which in logs sometimes write key word which is for me important, and I want to highlight this word in color in my terminal, but also important is still see all content logs in real time (--follow). I just tried command
docker logs -f my_app --tail=100 | grep --color -E '^myWord'
but not working.
So exist some way to do this ?
I use ccze. as #aimless said, grc is the great utility also. It easy to install by sudo apt install ccze for debian/ubuntu-like OS
But if you want to colorize stderr, you need to redirect stderr output to stdout. For example:
docker logs -f my-app 2>&1 | ccze -m ansi
arg -m ansi helps if you want to scroll output normally
UPD:
ccze can be very slow. If you encounter this, try running ccze with the nolookups option: ccze -o nolookups.
originally answered - https://unix.stackexchange.com/a/461390/83391
Try this.
docker logs -f my_app --tail=100 | grep --color=always -E '^myWord'
Note the "--color=always" argument.
Another option would be to use something like https://github.com/jlinoff/colorize. I wrote it to specifically address situations like this. For example it has the ability to specify different colors for each pattern (see the help for details).
Here is an example of how to use it for your case.
$ curl -L https://github.com/jlinoff/colorize/releases/download/v0.8.1/colorize-linux-amd64 --out colorize
$ chmod a+x colorize
$ ./colorize -h
$ docker logs -f my_app --tail=100 | ./colorize '^myWord'
$ # really make it standout.
$ docker logs -f my_app --tail=100 | ./colorize -c red+greenB+bold '^myWord'
try grc. Follow the instruction to install and just pipe the logs output:
docker logs -app | grc

Grep exact string not working when piped

If I cat text file containing mysqld_safe and mysqld then grep -w works as expected. But when piped with PS output it does not work.
ps -ef | grep -w mysqld
Output's both lines.
/usr/bin/mysqld_safe
/usr/libexec/mysqld
I am expecting only mysqld. I'm aware of exclude option grep -v mysqld_safe.
Version - grep (GNU grep) 2.5.1
If you have pgrep, using pgrep -x mysqld would be better choice than ps + grep
From man pgrep
pgrep, pkill - look up or signal processes based on name and other attributes
-x, --exact
Only match processes whose names (or command line if -f is specified) exactly match the pattern.
-l, --list-name
List the process name as well as the process ID. (pgrep only.)
-c, --count
Suppress normal output; instead print a count of matching processes. When count does not match any‐
thing, e.g. returns zero, the command will return non-zero value.
-n, --newest
Select only the newest (most recently started) of the matching processes.

How do I grep for a pattern in which the pattern is a shell-expansion that generates a list?

echo $'one\ntwo\nthree' | grep -F -v $(echo three$'\n'one)
Output should in theory be the string two
I've read that the -F command lets grep interpret each line as a list connected by 'or' qualifier.
Only mistake is some missing double-quotes:
echo $'one\ntwo\nthree' | grep -F -v "$(echo three$'\n'one)"
Also, keep in mind that this will also filter out "threesome", "someone", etc...
(#etan-reisner points out that running set -x before the original and the fixed command can be used to observe the difference the double-quotes make here, and, more generally, is a useful way to debug bash commands.)

Why does this grep -F not work?

I've used grep -F extensively at work (CentOS) to ignore regex pattern in the match. Now here's what I'm trying at home (Ubuntu 14.04):
$ cat file
Here is
the -F
you were looking
for!
~$ grep -F '-F' file
_
The underscore is meant to show a blinking cursor, as if it's waiting for input. Could it be because Ubuntu's grep doesn't follow all POSIX switches (I read that -F was specified by POSIX) or am I making a mistake somewhere?'
===== Update ======
Interestingly, it fails only when there's a newline following -F. If you change the text to, say, -F option, then the line matches. A bug in grep?
Specifying the same argument twice has no effect, so
grep -F '-F' file
is the same as grep -F file, which of course searches for the fixed-string file in its standard input.
The single-quotes are a red-herring. They protect the -F from any expansion by the shell (like glob-expansion, variable expansion, command substitution, etc.), and are removed by the shell before grep sees the -F.
What you need to do is use grep's -e pattern argument:
grep -F -e '-F' file
Given that context, the -F will be interpreted as the pattern. The single-quotes are still redundant. You could single-quote every other arg. I left them in because it helps humans come to the right conclusion at first glance, and it's generally not bad practice to quote stuff that could contain shell meta-characters in a future version of the script, even if it's currently safe.

Resources