I need to print all my database configuration, my project uses laravel and CI framework. So in shorts I'm looking for following file.
.env
→ located at/var/www/example_system/.env
database.php
→ located at/var/www/example_system/application/config/database.php
core_db.php
→ located at/var/www/example_system/app/core/core_db.php
I'm using following find command to perform this task.
find /var/www -maxdepth 4 -type f -name ".env" -not \( -path "/var/www/*/config" -prune \) -o -path '*core/*' -name "core_db.php" -o -path '*config/*' -name "database.php"
Which print.
/var/www/baloon/app/core/core_db.php
/var/www/infinys/application/config/database.php
/var/www/duffyweb/.env
/var/www/duffyweb/config/database.php
/var/www/loseweb/.env
/var/www/loseweb/config/database.php
/var/www/resto_app/application/config/database.php
This however fails to meet my need, as it still outputting both
/var/www/duffyweb/config/database.php
/var/www/loseweb/config/database.php
even though (I thought) I already explicitly exclude it on my find command using -name ".env" -not \( -path "/var/www/*/config" -prune \)
parameter.
So my question is How can I exclude something from find, if a directory has specific file in it. In this case if there was .env
file, I want find to exclude config/database.php
as I prioritize .env
over database.php
CodePudding user response:
Let's assume example_system
represents only one hierarchy level and you always want to print core_db.php
if the file exists.
The following, rather complex, find
command is probably not far:
find /var/www -maxdepth 4 -type f \( \
-name .env -o -name core_db.php -o \
-name database.php -exec sh -c '! [ -f "$(dirname "$1")"/../.env ]' _ "{}" \; \
\) -print
The idea is to add a condition for database.php
files with the -exec
action. The action is a call to a sub-shell that will return true only if a file named .env
does not exist two hierarchy levels under the database.php
file. The sub-shell script is rather simple:
! [ -f "$(dirname "$1")"/../.env ]
It takes one argument: the path of the database.php
file. It is not called directly as the -exec
parameter. Instead, it is called as the script parameter of sh -c
:
sh -c 'script' argv0 argv1...
argv0
corresponds to the $0
parameter of the script (unused, thus the _
which I frequently use as don't-care) and argv1
corresponds to the $1
positional parameter.
But as it is a bit complex, a more straightforward bash loop may be easier to understand and maintain:
for d in var/www/*/; do
e="${d}.env"
db="${d}application/config/database.php"
c="${d}app/core/core_db.php"
if [ -f "$e" ]; then
echo "$e"
elif [ -f "$db" ]; then
echo "$db"
fi
if [ -f "$c" ]; then
echo "$c"
fi
done