Рейтинг:3

Сценарий оболочки продолжает выполняться, даже если он был истинным

флаг in

У меня есть простой сценарий оболочки, чтобы проверить, существует ли пользователь, если нет, добавьте этого пользователя

#!/usr/bin/bash
эхо "Введите пользователя"
читать -r пользователь
если [ "$(id -u "$user" &>/dev/null)" = 1 ]; тогда
  эхо "пользователь существовал"
еще
  пользовательдобавить "$ пользователь"
  эхо "добавить пароль"
  пароль "$пользователь"
  echo "$user" &>>text.txt
  эхо "сохранено"
фи

Но он не отображает "эхо-пользователь существует". вместо этого он отображается так:

Введите пользователя

abcdef

useradd: пользователь 'abcdef' уже существует

добавить пароль

Новый пароль: 

В таком случае abcdef существующий пользователь

Пожалуйста, дайте мне знать, что здесь не так, большое спасибо.

MatsK avatar
флаг mp
Совет по устранению неполадок: запустите команду `id -u testuser` и проверьте, равен ли результат 1. Поскольку 1 – это единственное, что приведет к `echo «Пользователь существует»`
raj avatar
флаг cn
raj
@MatsK Даже 1 не будет продолжаться, так как вывод из `id` перенаправляется в `/dev/null`.
Terrance avatar
флаг id
После проверки `id -u $user &>/dev/null` используйте `echo $?`, и это даст либо 0, либо 1. 0 означает `код выхода 0` или true, 1 означает `код выхода 1` или ложный. Или у вас может быть `if [[ $? == 0 ]]; потом` и т. д.
raj avatar
флаг cn
raj
@Terrance Проще сразу использовать `id -u $user &>/dev/null` как условие в `if`.
Terrance avatar
флаг id
@raj не во всех случаях. На самом деле делать это с операторами `case` работает очень хорошо. `id -u` создает номер идентификатора пользователя, а не 1 или 0. Таким образом, вывод `id -u` в >/dev/null избавит вас от 1000, если это идентификатор пользователя.
raj avatar
флаг cn
raj
@Terrance Посмотрите на мой ответ ниже. Использование команды непосредственно в качестве условия для `if` (без ненужных `$(...)`) проверяет ее код выхода, а не вывод.
Terrance avatar
флаг id
@raj Это тоже сработает. Мой просто другой способ.
Рейтинг:9
флаг cn
raj

Следующее условие в вашем скрипте:

если [ "$(id -u "$user" &>/dev/null)" = 1 ]; тогда

никогда не будет правдой. Это было бы правдой Только если вывод команды id -u "$user" &>/dev/null будет одна цифра 1, но поскольку любой вывод этой команды перенаправляется на /dev/ноль, этого никогда не будет.

Замените эту строку на

если { id -u "$user" &>/dev/null ; } тогда

Это условие проверяет статус выхода команды (а не ее вывод нравиться $(...) делает) и будет истинным, если команда id -u "$user" &>/dev/null преуспевает (то есть пользователь существует) и false, если он терпит неудачу (то есть пользователь не существует).

флаг in
Спасибо за ваш ответ, это работает!!v Но какая разница между [] и {}?
raj avatar
флаг cn
raj
`[` — это **команда** (эквивалент `test`; см. `man [``), используемая для проверки результата различных условных выражений. `{}` — это просто круглые скобки для заключения команды. На самом деле, мы можем вообще пропустить `{}` (в то время как вы **не можете** пропустить `[]`): `if id -u "$user" &>/dev/null ; then` также будет работать, только менее читабелен.
флаг in
я не понимаю `[`это команда для проверки значения, тогда в моей команде '"$(id -u "$user" &>/dev/null)" = 1`, почему она не возвращает true, я имею в виду , `"$(id -u "$user" &>/dev/null)"` вернет 0 или 1, верно?
raj avatar
флаг cn
raj
Значение `$(command)` является **выводом** команды, т.е. текст, который печатает команда. Поскольку вы перенаправляете этот вывод в `/dev/null`, команда ничего не печатает. Таким образом, значение `$(id -u "$user" &>/dev/null)` всегда будет **пустой строкой**. Вы сравниваете эту пустую строку с цифрой 1, которая никогда не может вернуть истину.
флаг in
`{` и `}` лишние. `if id -u "$user" &>/dev/null; то достаточно.
raj avatar
флаг cn
raj
@JanHudec Я знаю, но код более понятен с `{}`. Они там просто для стиля :)
Рейтинг:2
флаг id

Ответ @raj на 100% правильный для упрощения кода.

Это всего лишь несколько альтернативных способов использования кодов выхода, которые, возможно, проливают немного больше света на то, как их можно использовать.

Код выхода можно проверить, выполнив эхо $? сразу после вашей команды id -u $user &>/dev/null который не нужно заключать в $(..) или что-то в этом роде.

Просто попробуй id -u <имя пользователя> &>/dev/null а затем введите эхо $? чтобы проверить код выхода.

Пример:

terrance@terrance-ubuntu:~$ id -u terrance &>/dev/null
terrance@terrance-ubuntu:~$ эхо $?
0
terrance@terrance-ubuntu:~$ id -u mark &>/dev/null
terrance@terrance-ubuntu:~$ эхо $?
1

В приведенном выше примере пользователь отметка не существует на моем компьютере, поэтому статус выхода 1.

Используя код выхода, вы можете поместить его в кейс заявление вместо если еще утверждение.

#!/бин/баш
эхо "Введите имя пользователя"
читать -r пользователь
id -u "$user" &>/dev/null
случай $? в
    0) echo "Пользователь существует";;
    1) adduser $пользователь
       эхо "добавить пароль"
       пароль $пользователь
       эхо $пользователь >> text.txt
       эхо "сохранено";;
эсак

Интересно, что с помощью если [ ]; тогда все еще можно использовать, добавив эхо $? в вашу проверку if, но я заметил, что вы проверяли, существует ли 1, но 1 означает, что код вышел с 1, означающим, что он не найден.

Добавление будет работать так же.

#!/бин/баш
эхо "Введите имя пользователя"
читать -r пользователь
если [ $(id -u "$user" &>/dev/null; echo $?) == 0 ]; тогда
    эхо "Пользователь существует"
еще
    добавочный пользователь $ пользователь
    эхо "добавить пароль"
    пароль $пользователь
    эхо $пользователь >> text.txt
    эхо "сохранено"
фи
флаг in
Спасибо, я многому научился из вашего ответа, но я не понимаю, почему `echo $`, что это такое ??
Terrance avatar
флаг id
@ LêQuá»cKhánh Может быть, это здесь может пролить немного больше света на `echo $?` для проверки команд выхода: https://askubuntu.com/questions/646526/what-is-is-it-a- переменная
Terrance avatar
флаг id
@LêQuá»cKhánh Кроме того, при проверке `id -u "$user" &>/dev/null; echo $?` теперь 2 команды как 1.
флаг in
Это лайфхак для shell bash =), большое спасибо
Terrance avatar
флаг id
@LêQuá»cKhánh Добро пожаловать!
флаг in
Могу я задать вам еще один вопрос? Я знаю, что `&>` переместит stdout и stderr в , но в этом случае зачем нам перемещать эти значения в `/dev/null` , все, что я понимаю сейчас, это `id -u "$user" &>/dev/ null` вернуть 0 или 1, затем перейти к `/dev/null` Но все, что нам нужно, это проверить, было ли 0 или 1, но зачем нам переходить к `/dev/null`, если я использую только `id -u "$user" &>/dev/null`, что случилось? На самом деле этот код с нашего сайта и не совсем понимаю
Terrance avatar
флаг id
@ LêQuá»cKhánh Использование `/dev/null` — это способ стереть стандартный вывод, чтобы вы не видели его на экране. Это просто способ содержать вещи в чистоте. Вы можете получить тот же код выхода или статус, не используя его, но вы увидите все эти выходные данные на экране, и это может затруднить использование вашего кода. Не стесняйтесь тестировать свой код без `&>/dev/null`, так как он все еще должен работать.
Terrance avatar
флаг id
@ LêQuá»cKhánh 0 и 1 — это только статус выхода. Если вы запустите `id -u $user` без каких-либо слов после него, он выдаст идентификационный номер пользователя. Например, мое имя пользователя дает 1000, так как это мой идентификационный номер пользователя. Но если я введу `echo $?` после этой команды, она все равно выдаст 0, поскольку статус выхода прошел.
флаг in
Спасибо огромное
флаг in
Я просто пытаюсь войти с помощью `user1="$(id -u "$user")"` и `echo "User is $user1"` и возвращает 1007, что это значит?
Terrance avatar
флаг id
@LêQuá»cKhánh `id -u` выдает UID или идентификационный номер пользователя, а не статус выхода. Вы должны запустить `echo $?` в качестве следующей команды, чтобы увидеть статус выхода команды `id -u`.
флаг in
теперь понял, спасибо большое

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.