0

I'm using Bourne Shell: #!/bin/sh

I'm doing a script that find a file/s that match a specific pattern and while the command is executing, copy every output to a new directory.

myscript.sh

#!/bin/sh

ssh user@hostname find /path/to/find/file* -mtime 10 | while read -r LINE
do
scp -r user@hostname:$LINE /path/to/destination/
done

That's my initial script to find the files with the same filename pattern but there are some other files that don't have the same filename pattern. So I decided to use grep and pipe it to find but it doesn't read the ssh anymore instead it finds the files in the current directory which clearly doesn't exist.

Here's an example:

ssh user@hostname find /path/to/find/* -mtime 10 | xargs zgrep -il 'pattern_to_find' | while read -r LINE
do
    scp -r user@hostname:$LINE /path/to/destination/
done

See I wanted to use this command find /path/to/find/* -mtime 10 | xargs zgrep -il 'pattern_to_find' but when I incorporate it with a while using | it doesn't work fine anymore.

1

Don't use find with xargs piping. If you do it, try to use with find -print0 and xargs -0 to use null character instead new lines as file names delimeter.

From man find:

-print0

True; print the full file name on the standard output, followed by a null character (instead of the newline character that -print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.

So, you command will be:

ssh user@hostname find /path/to/find/ -type f -mtime 10 -print0 | xargs -0 zgrep -il 'pattern_to_find'

But -print0 it's not POSIX (if I'm not mistaken). Thus, there is only one way, read below.

Or the best way to use -exec option of find command without xargs piping:

ssh user@hostname find /path/to/find/ -type f -mtime 10 -exec grep -il 'set' {} + ;

See How can I recursively search all files for a string?

  • Thanks! Seems like while loop doesn't read my first command and your first suggestion with that pipe. I think it executes every command pipe-by-pipe that's why the output of my script can't find the directory because once find is done, grep only looks for the matching pattern in the local server which in return doesn't have the files I'm looking for. I'm using your second suggestion by the way. – WashichawbachaW Nov 15 '17 at 6:48
  • @WashichawbachaW, see more about ssh with a few command. It may help you. stackoverflow.com/questions/4412238/… – Egor Vasilyev Nov 15 '17 at 6:52
0
ssh -n user@hostname 'find /root/git/ -mtime 10 | while read -r LINE ; do echo $LINE; done'

-n option from man ssh:

-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. # ... # The ssh program will be put in the background. (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)

EDITED

OK, then from find file names should be echoed(as strings) to xargs to pass as an argument to grep/zgrep, check it out (no -print0 needed):

ssh user@hostname find /path/to/find/* -mtime 10 | xargs echo | zgrep -i 'pattern_to_find' | while read -r LINE do scp -r user@hostname:$LINE /path/to/destination/ done

  • I'm looking for a solution to insert grep in my script. You didn't answer my question. – WashichawbachaW Nov 15 '17 at 5:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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