Both your command lines generate a long list of files. I have to stop the command pressing [Ctrl]+c keys
I think I have to save the printout to a file and read the content afterwards
Wow, how many websites are you dealing with?
If you wanted, you could redirect the output from my commands to a file and then view the file afterwards?
And to free up the terminal whilst it's running, you can run the command in the background.
e.g.
Add the following to the end of both of the commands I posted previously:
But replace
/path/to/outputfile
with the path to save the file to. And I'd suggest using a different file-name for the output of each command, because > will overwrite the output file if it already exists!
With the above modification, you can continue to use the terminal whilst the job runs in the background. And when the job has finished you'll have a text file that you can view with the results in it.
What command lines I have to execute finding files containing following pattern;
<FilesMatch '.(php|php5|suspected|py|phtml)$'>
Order allow,deny
Deny from all
</FilesMatch>
Offhand, you could write a script which uses find and grep to create a list of files containing a basic pattern, similar to my previous examples. the list could be written to a temporary file. Then use sed on each file in the list to find instances of the multi-line pattern you have specified.
Which would look something like this:
Bash:
#!/usr/bin/env bash
tmpDir="$(mktemp -d)"
tmpFile="$tmpDir/tempFile"
find ./ -name ".htaccess" -type f -exec grep -Rl "php\|php5\|suspected\|py\|phtml" {} \; > "$tmpFile"
while read -r filename; do
echo "In $filename:"
sed -n "/<FilesMatch .*php\|php5\|suspected\|py\|phtml.*>\nOrder allow.*deny\nDeny from all\n/,/<\/FilesMatch>/p" "$filename"
echo
done < "$tmpFile"
rm -r "$tmpDir"
Save that as whatever you'd like to call it. Make it executable using
chmod +x /path/to/script
, where
/path/to/script
is whatever you called the script.
Then run it.
The above script uses
mktemp
to create a temporary directory in
/tmp/
. Then we set up a filename for a temporary file to store in our temporary directory.
Then we use find to find all .htaccess files, and uses
grep
in
find
's
-exec
section, to determine whether any of them contain the basic file filter you're interested in. Any .htaccess files that match are written to our temporary file, in the temporary directory in /tmp/.
Then we use a
while read
loop to read each filename in the temporary file and use
sed
to find the multiline pattern you're interested in and show them on the screen using
sed
's
p
(print) command.
Finally we use the
rm
command to recursively remove the temporary directory and temporary file that we added to
/tmp/
.
Running the above script will yield output that looks like this:
In /path/to/website1/.htaccess:
<FilesMatch '.(php|php5|suspected|py|phtml)$'>
Order allow,deny
Deny from all
</FilesMatch>
In /path/to/website2/.htaccess:
<FilesMatch '.(php|php5|suspected|py|phtml)$'>
Order allow,deny
Deny from all
</FilesMatch>
And if you have a lot of websites, you may have a lot of lines that look like that. Also, if there are multiple occurrences in a file - you'll get multiple copies output too.
So when you run the script, you may want to consider redirecting the output to a file so you can take a look at it.
e.g.
Code:
./script > /path/to/outputFile
Optionally, you might want to redirect and run it in the background, as a background job, to free up your terminal:
Code:
./script > /path/to/outputFile &
Or perhaps pipe the scripts output through a pager like
less
, or
more
, or a terminal based browser like
w3m
.
e.g.
However you decide to run the script, if you're happy that the script has picked out the correct lines in the files, the next thing you could do is modify the
sed
command in the script to delete the offending lines from the files:
Bash:
sed -i -n "/<FilesMatch .*php\|php5\|suspected\|py\|phtml.*>\nOrder allow.*deny\nDeny from all\n/,/<\/FilesMatch>/d" "$filename"
In the above snippet, we've added sed's
-i
option (in-place editing) - which will directly edit the files.
And instead of using
sed
's
p
(print) command to print the lines, we're using the
d
(delete) command to delete the matching lines.
So if you edit the
sed
command in the above script to do that, the output will look like this:
In /path/to/website1/.htaccess:
In /path/to/website2/.htaccess:
etc etc.....
But those are just from the echo commands in the script.
It might be useful to leave the echo commands in there, so you can see which files were edited, but optionally, you could comment them out, or delete them.
Also, it's worth noting that because the modified
sed
attempts to modify the .htaccess files to remove the matching lines, you will need to run the script as root. Either directly logged in as root, or via another mechanism like
sudo
, or
wheel
(depending on your distro).
So if you get any errors about permissions after editing the
sed
command to delete the matching lines from the files - you will need to run the script as root.