Утилита id
при использовании с ее опцией -u
выводит UID текущего пользователя. Если этот UID равен нулю, то пользователь является пользователем root. Добавлять новых пользователей должен только пользователь root.
Таким образом, сценарий проверяет значение UID пользователя, запустившего сценарий, на ноль и выполняет привилегированные действия (, не показанные в сценарии в вопросе ), только если пользователь является пользователем root.
Возможно, лучший способ справиться с этим в скрипте, если для всего скрипта требуется root, — это проверить, не равен ли UID -нулю в начале, и выйти с ошибкой, если он:
if [ "$(id -u)" -ne 0 ]; then
echo 'You are not root. Try again with sudo.' >&2
exit 1
fi
Что касается $?
, это специальная переменная оболочки, которая всегда содержит статус выхода последней выполненной команды. Очень редко нужно использовать это напрямую, так как if
более чем способен работать напрямую сgrep
:
if grep -q "^$username" /etc/passwd; then
printf 'User "%s" already exists\n' "$username" >&2
exit 1
fi
Здесь if
будет использовать статус выхода grep
.Мы используем grep
с -q
, чтобы он не производил никаких выходных данных и не анализировал весь файл после любого первого совпадения. Он просто возвращает статус выхода, который будет использовать if
. Нам также не нужно egrep
, так как регулярное выражение не является расширенным регулярным выражением(egrep
идентичноgrep -E
).
Также обратите внимание, что диагностические сообщения следует записывать в стандартный поток ошибок. Вы можете сделать это, перенаправив свои сообщения с помощью >&2
. Кроме того,printf
предпочтительнее echo
при выводе переменных данных .
Если вы работаете в системе, где используется служба каталогов, такая как NIS или LDAP, поиск существующего пользователя в /etc/passwd
может оказаться бесполезным, поскольку фактические пользователи могут храниться в отдельной базе данных.
В таких системах может быть лучше использоватьgetent passwd "$username"
(это будет работать и в системах, отличных от -NIS/LDAP ). Это вернет запись базы данных паролей для конкретного пользователя или завершит работу с не -нулевым статусом выхода, что означает, что мы могли бы использовать этот в нашем тесте:
if getent passwd "$username" >/dev/null; then
printf 'User "%s" already exists\n' "$username" >&2
exit 1
fi
Обратите внимание, что useradd
нельзя добавлять пользователей в базы данных NIS или LDAP...
Хотя, строго говоря, ничего из вышеперечисленного не требуется, так как useradd
не должен делать ничего полезного, если текущий пользователь не root или если добавляемый пользователь уже существует.
В большинстве синтаксисов со строками в кавычках обратная косая черта перед знаком препинания обозначает этот знак препинания вместо того, чтобы позволить знаку пунктуации иметь свой обычный особый эффект. В частности, две обратные косые черты обозначают одну обратную косую черту. Обратная косая черта, за которой следует буква или цифра, обычно работает противоположным образом :: символ имеет особый эффект.
Заключите код sed в одинарные кавычки '…'
, чтобы защитить его от расширения оболочки. Если вам нужна одинарная кавычка внутри кода sed, используйте'\''
(кавычка -обратная косая черта -кавычка -кавычка :первая кавычка завершает одиночный сегмент -в кавычках, затем есть символ кавычки, который интерпретируется буквально, потому что перед ним стоит обратная косая черта,и последняя цитата начинает новый одиночный -цитируемый сегмент ).
Sed — хороший инструмент, если нужно заменить небольшое количество последовательностей обратной косой черты. В команде sed s
используйте двойную обратную косую черту -для обозначения обратной косой черты. Используйте последовательные команды s
для каждой последовательности обратной косой черты. Поместите преобразование, которое преобразует двойную обратную косую черту -в обратную косую черту, последней, чтобы результирующая обратная косая черта сама не заменялась. Здесь, в последней команде, я использую .
для обозначения любого символа в регулярном выражении, \(.\)
делает его нумерованной группой (обратите внимание, что здесь обратная косая черта делает скобки специальными :это особенность базового синтаксиса регулярных выражений , который sed использует ), а \1
обозначает эту группу в замещающем тексте.
sed -e 's/\\u003c/</g; s/\\u003e/>/g; s/\\n/\n/g; s/\\\(.\)/\1/'
В качестве альтернативы, чтобы преобразовать последовательности обратной косой черты с произвольным номером после \u
, вы можете использовать Perl. В Perl есть операторs
, похожий на команду sed s
, но с немного другим синтаксисом регулярных выражений , и замена позволяет писать код Perl.
perl -pe 's/\\u([0-9a-f]{4})/chr($1)/eg; s/\\n/\n/g; s/\\(.)/$1/g'
Эти символы относятся к тегам <
и >
HTML (или аналогичным тегам ). Вы можете удалить их, но я предлагаю вам сначала преобразовать их, чтобы сохранить файловую структуру, а затем попытаться удалить их, если они не нужны.
В зависимости от размера вашего ввода вы можете сделать это:
$ echo -e ($cat encodedfile.txt) > decodedfile.txt
Для больших файлов это должно сработать:
$ cat encodedfile.txt | while read -r a; do echo -e $a; done > decodedfile.txt