как создать строку regex, где Вы не знаете, что выйти

У меня есть 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'
2
задан 3 December 2018 в 14:07

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
2
ответ дан 2 December 2019 в 03:30

Другие вопросы по тегам:

Похожие вопросы: