我有一个 passwd 文件,其中包含 root 的行是:
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'
在调用之前将其转义
sed
:但是,如果您的哈希包含
"
, 或\
, 以及如果它包含,那将会中断,因为当替换运算符的右侧存在&
sed 时,sed 会将其读作“匹配的任何内容” 。&
所以你也需要逃避那些:最后,如果您的散列包含
:
它将破坏整个事情,因为它不能被转义,因为它是 passwd 文件中的分隔符。所以我会为此添加一个测试: