在bash

时间:2015-07-30 15:16:10

标签: regex linux bash passwords

我有一个在Linux机器上运行的脚本,它可以读取命令并在某些事件上调用程序。

我们需要记录这些命令,但在使用密码参数时,通过连续放入五个X(XXXXX)来过滤/替换密码参数。

输入示例

bash脚本接收的输入有一个命令类型,后跟各种参数,如下所示:

  • adduser --username="foo" --password="bar"
  • remove --username="foo"
  • listusers
  • changepass --username="foo" --password="bar"

基本格式为command parameter="" parameter=""...

记录值的示例

上述值在日志中如下所示:

  • adduser --username="foo" --password="XXXXX"
  • remove --username="foo"
  • listusers
  • changepass --username="foo" --password="XXXXX"

我尝试了什么

我尝试使用bash替换,但在第一种情况下,我们没有引用密码(我们后来发现这将通过引号传递)。它会切断密码后的所有内容。第二种选择根本就不做替换。

  • echo "${value%password=*}password=XXXXXX" >> somelog.log
  • echo "${value/password=\"(.*?)\"/password=xxxxx }" >> somelog.log

我觉得第二种选择很接近,但我遗漏了一些东西。如果有人能指导我,我们将不胜感激。

3 个答案:

答案 0 :(得分:3)

是否要求在bash中本地执行此操作?

通过sed管道可能会更容易。但是如果你想使用bash我会建议以下内容更改前缀为--password =后跟任何非空格(因此它捕获引用和不带引号的密码)的任何内容。我使用了//如果需要在一行上有多个--password实例。需要在脚本中启用extglob(扩展模式匹配)才能使其正常工作。

shopt -s extglob
"${value//--password=+([! ])/--password=XXXXX }"

参考文献:
   http://wiki.bash-hackers.org/syntax/pattern
   http://wiki.bash-hackers.org/syntax/pe#search_and_replace

TESTDATA:

adduser --username="foo" --password="bar"
adduser --username="foo" --password=bar
remove --username="foo"
listusers
changepass --username="foo" --password="bar" --something="else"
changepass --username="foo" --password="bar" --something="else" --password="again"

变成:

adduser --username="foo" --password=XXXXX
adduser --username="foo" --password=XXXXX
remove --username="foo"
listusers
changepass --username="foo" --password=XXXXX  --something="else"
changepass --username="foo" --password=XXXXX  --something="else" --password=XXXXX 

编辑:我忘了提到为此需要激活extglob。

答案 1 :(得分:2)

我不喜欢bash替换,更喜欢使用sed来完成这样的任务。怎么样:

echo "$value"|sed 's/password="[^"]*"/password="XXXXX"/' >> somelog.log

答案 2 :(得分:1)

Shell替换扩展是模式而不是正则表达式。

使用"${value/password=\"*\"/password=XXXXX}"但请注意,这将是贪婪的(但你不能用这种方法避免这种情况)虽然它似乎处理密码字符串中的转义引号

如果您需要担心以后的参数,那么您需要使用其他东西(可以使用正则表达式)。

类似的东西:

[[ "$f" =~ (.*password=)\"[^\"]*\"(.*) ]]; echo "${BASH_REMATCH[1]}XXXXX${BASH_REMATCH[2]}"

但这有转义报价的问题(它提前结束了匹配)。

但是RSchulze的答案更好。