感谢: @Diego Torres Milano
https://stackoverflow.com/a/48569466/175063
#!/bin/bash
find /home -type f -name "wp-config.php" -print0 | while read -rd $'\x00' f
do
cat '[%s]\n' "$f" | grep DB_NAME | cut -d \' -f 4
done
但是,似乎缺少一些东西:
./test.sh: line 5: unexpected EOF while looking for matching ``'
./test.sh: line 8: syntax error: unexpected end of file
结果:
#!/bin/bash
find /home -type f -name "wp-config.php" -print0 | while read -rd $'\x00' f
do
printf '%s\n' "$f"
WPDBNAME=`cat '%s\n' "$f" | grep DB_NAME | cut -d \' -f 4
WPDBUSER=`cat '%s\n' "$f" | grep DB_USER | cut -d \' -f 4
WPDBPASS=`cat '%s\n' "$f" | grep DB_PASSWORD | cut -d \' -f 4
echo $WPDBNAME
echo $WPDBUSER
echo $WPDBPASS
done
最终,我想要的是:
f 0 = 4
f 1 = 5
...
谢谢!
答案 0 :(得分:2)
这里有很多问题;首先,我将第二个@Cyrus' shellcheck.net的推荐 - 它会发现一些常见错误,包括脚本中的几个错误。无论如何,我看到的问题是:
您获得的错误是由于不平衡的反引号造成的。问题的原始版本有这一行:
cat '[%s]\n' "$f" | grep DB_NAME | cut -d \' -f 4`
并且该行末尾的单独反引导将导致错误,例如您正在获得的错误。编辑后的版本没有(并且因此不会给出报告的错误),但是"我想要的东西是"脚本有如下行:
WPDBNAME=`cat '%s\n' "$f" | grep DB_NAME | cut -d \' -f 4
在=
之后有一个无与伦比的反引号。我的建议是使用$( )
而不是反引号 - 它们更容易阅读(因此更难搞乱),在功能上等同,并且没有反引号导致的微妙转义问题。所以,你应该使用类似的东西:
WPDBNAME=$(cat '%s\n' "$f" | grep DB_PASSWORD | cut -d \' -f 4)
除此之外仍然是错误的。 '%s\n'
部分是printf
格式字符串,在您复制的示例中需要,但在此处完全不相关。如果您将该参数提供给cat
命令,它将尝试打开名为%s\n
的文件并失败。把它关掉:
WPDBNAME=$(cat "$f" | grep DB_PASSWORD | cut -d \' -f 4)
下一个不是一个真正的问题,就像一般建议一样:只要你看到cat somefile | somethingcommand
,cat
命令实际上并没有做任何有用的事情(它被称为&#34;无用的猫&#34;)。它可以替换为somecommand <somefile
,或者,如果命令直接支持输入文件名,则somecommand somefile
。 grep
支持输入文件名,因此您只需使用grep DB_PASSWORD "$f"
。
实际上,grep something | cut something
几乎总是可以使用awk
进行简化。只需使用/pattern/
搜索相关行,print
搜索相关字段(使用-F
定义字段分隔符):
WPDBNAME=$(awk -F \' '/DB_NAME/ {print $4}' "$f")
您没有遇到此问题,但使用全方位变量名称可能会造成麻烦,通常被视为不良做法。有许多变量对shell和/或其他程序有特殊意义,如果你不小心使用其中一个,它可能会产生坏/怪异的效果。经典案例是将PATH
用于寻找可执行文件的地方列表之外的其他内容,然后使用suddenly getting "command not found" errors。
坚持使用小写或混合大小写变量,您不必担心这一点。
打印结果时,不要对引号进行双引号。使用echo "$wpdbname"
代替echo $wpdbname
来防止因分词和全局扩展而导致的奇怪现象。
但实际上,您根本不需要将各种参数捕获到变量中,您可以直接打印它们。也就是说,替换:
wpdbname=$(awk -F \' '/DB_NAME/ {print $4}' "$f")
echo "$wpdbname"
使用:
awk -F \' '/DB_NAME/ {print $4}' "$f"
最终剧本:
#!/bin/bash
find /home -type f -name "wp-config.php" -print0 | while read -rd $'\x00' f
do
printf '%s\n' "$f"
awk -F \' '/DB_NAME/ {print $4}' "$f"
awk -F \' '/DB_USER/ {print $4}' "$f"
awk -F \' '/DB_PASSWORD/ {print $4}' "$f"
done
注意:可以将单独的awk
命令替换为搜索&amp;的单个XSLT
命令。打印所有三个值。但是,按照它们在文件中出现的顺序打印它们,不一定是您期望的顺序。所以这可能更好。
答案 1 :(得分:0)
在响应者的指导下,我已经能够达成一个解决方案,现在正在运行的是一个cron工作。
#!/bin/bash
# delete files older than 7 days
find /home/dummyacount/sqlbackups/ -type f -name '*.gz' -mtime +7 -exec rm {} \;
# set a date variable
DT=$(date +"%m-%d-%Y")
find /home -type f -name "wp-config.php" -print0 | while read -rd $'\x00' f
do
printf '%s\n' "$f"
WPDBHOST=$(grep DB_HOST '%s\n' "$f" | cut -d \' -f 4)
WPDBNAME=$(grep DB_NAME '%s\n' "$f" | cut -d \' -f 4)
WPDBUSER=$(grep DB_USER '%s\n' "$f" | cut -d \' -f 4)
WPDBPASS=$(grep DB_PASSWORD '%s\n' "$f" | cut -d \' -f 4)
mysqldump -q -u "$WPDBUSER" -h "$WPDBHOST" -p "$WPDBPASS" "$WPDBNAME" | gzip -9 > "/home/dummyaccount/sqlbackups/$DT-$WPDBNAME.sql.gz"
done
我还必须回到:https://tomjn.com/2014/03/01/wordpress-bash-magic/
获取更多使用mysqldump整理的语法,但现在效果很好。