如何创建一个你不知道要转义什么的正则表达式字符串

如何创建一个你不知道要转义什么的正则表达式字符串

我有一个 passwd 文件,其中有以下行:

root:6UZSjeWUui3JQ:0:0:root:/root:/bin/sh

我希望将此行更改为:

root:$1$dog$cNv/OuAd7CMNdrhWsHXAR.:0:0:root:/root:/bin/sh

该密码使用以下方式生成:

hash=$(openssl passwd -1 -salt $salt angus)

其中嵌入了 / 字符。因此,这意味着我无法使用这个 sed:

sed -e "s/root:.*:0:0:/root:$hash:0:0:/" './test/etc/passwd'

我必须改为:

sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'

否则我会收到这个神秘的错误:

sed -e expression #1, char 32: unknown option to `s'

但是,如果生成的哈希中嵌入了 | 字符怎么办?如何使此脚本能够处理任何哈希?

这是我目前的脚本,如果哈希中嵌入了 | 字符,它将会失败。

例如如果像这样调用:

sudo ./justsed.sh angus dog

脚本:

#!/bin/bash

if [[ ! $1 || ! $2 ]]; then
    echo "Usage: justsed.sh <password> <salt>"
    exit 0
fi

# change salt to random chars for real use
salt=$2

# example: $1$dog$cNv/OuAd7CMNdrhWsHXAR.
hash=$(openssl passwd -1 -salt $salt $1)

printf "using the following hash: %s, updating file: %s\n" $hash "./test/etc/passwd"

echo "sed command with escaped /"
# this line works
sed -e 's/root:.*:0:0:/root:$1$dog$cNv\/OuAd7CMNdrhWsHXAR.:0:0:/' './test/etc/passwd'

echo "sed replace text"
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'

答案1

在调用之前先将其转义sed

hash=$(openssl passwd -1 -salt $salt $1 | sed 's|/|\\/|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'

"但是,如果您的哈希表包含、 或\,以及包含 ,那么这将中断,因为当出现在替换运算符的右侧&时,sed 会将其读为“匹配的内容” 。因此,您还需要转义这些:&

hash=$(openssl passwd -1 -salt $salt $1 | sed -E 's|(["/\@])|\\\1|g')
sed -e "s|root:.*:0:0:|root:$hash:0:0:|" './test/etc/passwd'

最后,如果您的哈希包含:该内容,则会破坏整个过程,因为它是 passwd 文件中的分隔符,因此无法转义。因此,我将为此添加一个测试:

if [[ "$hash" =~ /:/ ]];
then
    echo "Invalid password! Choose another"
    exit
fi

相关内容