用SED剪出Discuz的数据库用户名和密码的探讨

每次修改数据库密码就要修改mysqlhotcopy的陪住的密码比较麻烦,心血来潮,就像能不能用sed或者awk配合把密码剪出来


Discuz一般的配置文件格式如下

/*
[Discuz!] (C)2001-2006 Comsenz Inc.
This is NOT a freeware, use is subject to license terms

$RCSfile: config5.inc.php,v $
$Revision: 1.9 $
$Date: 2007/01/26 01:11:32 $
*/

// [CH] 以下变量请根据空间商提供的账号参数修改,如有疑问,请联系服务器提供商

$dbhost = 'localhost'; // 数据库服务器
$dbuser = 'user'; // 数据库用户名
$dbpw = '1234567809'; // 数据库密码
$dbname = 'discuz'; // 数据库名

。。。。。。。。。。。以下省略

// ============================================================================
define('UC_CONNECT', 'mysql');
define('UC_DBH............以下省略

那么用行数肯定不行,因为对应关系可以变化,实际上就是剪出来$dbpw后面和;之前的文字就可以了,为了简化处理,先把单独那几行拎出来之前,掐掉所有的空格和TAB制表符

TAB制表符干掉先 ,在干掉空格,最后取出$dbpw 的行

[bash]sed -n 's/\t//gp' config.inc.php |sed -n 's/ //gp' |grep \$dbpw [/bash]

更加明确的写法

[bash]sed -n 's/\t//gp' config.inc.php |sed -n 's/[[:space:]]//gp' |grep \$dbpw [/bash]

顺便补充一个删除空行的,虽然不干扰,还是最好没有

[bash]sed /^$/d[/bash]

这个写法非常巧妙,得记住了

关于正则表达式,我几乎全部忘记了,现在重新学习下

正则表达式元字符集(基本集)
^
锚定行的开始 如:'^grep'匹配所有以grep开头的行。
$
锚定行的结束 如:'grep$'匹配所有以grep结尾的行。
匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。
*
匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。
[]
匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
[^]
匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。
\(..\)
标记匹配字符,如'\(love\)',love被标记为1。
\<
锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。
\>
锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。
x\{m\}
重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。
x\{m,\}
重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。
x\{m,n\}
重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。
\w
匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。
\W
\w的反置形式,匹配一个或多个非单词字符,如点号句号等。
\b
单词锁定符,如: '\bgrepb\'只匹配grep。

~~~~~~~~~~~~~~~~~~~~

用于egrep和 grep -E的元字符扩展集
+
匹配一个或多个先前的字符。如:'[a-z]+able',匹配一个或多个小写字母后跟able的串,如loveable,enable,disable 等。
?
匹配零个或多个先前的字符。如:'gr?p'匹配gr后跟一个或没有字符,然后是p的行。
a|b|c
匹配a或b或c。如:grep|sed匹配grep或sed
()
分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。
x{m},x{m,},x{m,n}
作用同x\{m\},x\{m,\},x\{m,n\}
多条件匹配
grep -E "one|two|three"
~~~~~~~~~~~~~~~~~~~~~

Grep命令选项
-?
同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。
-b,--byte-offset
打印匹配行前面打印该行所在的块号码。
-c,--count
只打印匹配的行数,不显示匹配的内容。
-f File,--file=File
从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。
-h,--no-filename
当搜索多个文件时,不显示匹配文件名前缀。
-i,--ignore-case
忽略大小写差别。
-q,--quiet
取消显示,只返回退出状态。0则表示找到了匹配的行。
-l,--files-with-matches
打印匹配模板的文件清单。
-L,--files-without-match
打印不匹配模板的文件清单。
-n,--line-number
在匹配的行前面打印行号。
-s,--silent
不显示关于不存在或者无法读取文件的错误信息。
-v,--revert-match
反检索,只显示不匹配的行。
-w,--word-regexp
如果被\<和\>引用,就把表达式做为一个单词搜索。
-V,--version
显示软件版本信息。

ok

下面就是如何把

[bash]$dbpw='1234567809';//数据库密码[/bash]

中的1234567809给剪出来了

在这里我使用了两个方法

1.使用cut来截取,参见cut的使用例子一文

[bash]sed -n 's/\t//gp' config.inc.php |sed -n 's/[[:space:]]//gp' |grep \$dbpw|cut -d "'" -f 2 [/bash]

返回值就是1234567809, 就是数据库密码了
但是这个方法面临个问题 那就是如果我在写配置文件的时候,没有用单引号引用密码(在php里面,这种复制方法是允许的,但是就是如果密码含有特殊字符,比如'或者$的时候会出错),这时候用单引号截取就没有效果

2.截取掉那个$,这样

[bash]$dbpw='1234567809';//数据库密码[/bash]

就变成了

[bash]dbpw='1234567809';//数据库密码[/bash]

这是一个标准的shell赋值方式后面的//可以无视,因为;表示前面的shell已经执行完毕了
然后我们就得到了一个带值的变量$dbpw

3.更好的办法是考虑特殊符号的使用
假设我现在面对的是这句话

[bash]$dbpw='12345$7809';//数据库密码[/bash]

这样的话就好玩了
Does anyone have any ideas?

Author Info :
  • From:用SED剪出Discuz的数据库用户名和密码的探讨
  • URL:https://blog.ihipop.com/2010/03/812.html
  • Please Reserve This Link,Thanks!
  • 发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注