The Wayback Machine - https://web.archive.org/web/20150924013941/http://unix.stackexchange.com/questions/194807/finding-files-that-contain-multiple-strings
Sign up×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I am trying to find scripts that contain common malicious code, I need to match multiple strings within each file. What I am using is working but am not sure why I get the following in the output:

# egrep -rli --include='*.php' 'return base64_decode' . | xargs -0 grep -l 'isset' grep: ./wp-content/themes/twentyfourteen/js/menu61.php ./wp-content/themes/twentyfourteen/themes.php ./wp-content/themes/twentytwelve/file68.php ./wp-content/themes/twentythirteen/inc/page.php ./wp-content/themes/twentythirteen/inc/template.php ./wp-content/upgrade/include.php ./wp-content/plugins/wp-slimstat/browscap/diff8.php ./wp-content/plugins/quick-contact-form/gallery56.php ./wp-content/plugins/addthis/css/include.php ./wp-content/plugins/addthis/includes/include.php ./wp-content/plugins/tpc-memory-usage/images/code77.php ./wp-content/plugins/gotmls/images/index.php ./wp-content/plugins/tinymce-advanced/langs/object56.php ./wp-content/plugins/wp-security-audit-log/dirs70.php ./wp-content/plugins/wp-security-audit-log/css/list76.php ./wp-content/plugins/wp-security-audit-log/proxy.php ./wp-content/plugins/image-widget/lang/alias.php ./wp-content/plugins/my-page-order/template.php ./wp-content/uploads/2015/01/footer87.php ./wp-content/menu.php ./wp-includes/js/thickbox/db.php ./wp-includes/js/jquery/ui/footer39.php ./wp-includes/js/imgareaselect/general.php ./wp-includes/css/page25.php ./wp-includes/Text/Diff/Engine/dump.php : No such file or directory 

The output is good and is what I want but why does it show on line 1:

grep: ./wp-content/themes/twentyfourteen/js/menu61.php 

and the last line always shows:

: No such file or directory 

and lastly, piping it into a file doesn't work.

# egrep -rli --include='*.php' 'return base64_decode' . | xargs -0 grep -l 'isset' >> asd 
share|improve this question

2 Answers 2

What you're looking at is not a result, it's an error message. The format of grep's error when told to search through a non-existent file is grep: file name: No such file or directory. For example:

$ grep foo bar grep: bar: No such file or directory 

That's why you get the grep: at the beginning and the No such file or directory at the end. That is also why you can't redirect the output to a file, it's being printed to standard error, not standard output and you are redirecting the latter. You can save the output by using 2>> instead of >>. That, however, is not what you want since these are errors.

Your problem is that you're using -0 with xargs which tells it to expect null-separated data. Since your data is actually separated by newlines (each file is on a single line), xargs tells grep to look for a file of that name (the entire multiline set). What you want to do instead is:

 grep -Erli --include='*.php' 'return base64_decode' . | xargs grep -l 'isset' 

Or, if your file names can contain newlines and you have a version of grep that supports it, use grep's -Z flag to produce null-separated output:

grep -ZErli --include='*.php' 'return base64_decode' . | xargs -0 grep -l 'isset' 

Also note that I use grep -E instead of egrep. The egrep and fgrep are deprecated in favor of grep -E and grep -F, respectively.

share|improve this answer

Try running xargs without the -0 parameter. That parameter tells xargs to expect nul-separated arguments, which isn't the case here.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.

close