Принять имя пользователя в качестве ввода: если пользователь вошел в систему, отобразить запущенные процессы, принадлежащие пользователю

Я хочу написать скрипт, который принимает имя пользователя в качестве ввода командной строки. Если этот пользователь вошел в систему, он отобразит процессы, которые он выполняет. Если он / она не вошел в систему, то сценарий должен упомянуть об этом.

Моя попытка не работает:

#!/bin/bash
echo "Who are you?"
read user
echo $user
name=$(whoami)
if[$user == $name]
then
  top -u $user
else
  echo "not logged in"
fi
2
задан 16 December 2017 в 11:33

3 ответа

Можно использовать who -u управляйте для списка пользователей, которые зарегистрированы. Затем Вы могли использовать grep искать определенного пользователя в выводе, и выход с успехом, если найдено или выход с отказом иначе.

#!/bin/bash

read -p 'Enter username to check: ' user
if who -u | grep -q "^$user "; then
    top -u "$user"
else
    echo "User $user is not logged in"
fi

(Благодаря @dessert для сокращения who -u | ... часть!)

3
ответ дан 2 December 2019 в 01:29

Мне похоже на недоразумение задачи немного. Я предполагаю, что сценарий - что-то, что системный администратор использовал бы для проверения пользователей, таким образом, "Кто Вы?", и проверка, что пользователь, запускающий скрипт, ввел их собственное имя пользователя (который является тем, что Ваш сценарий пытается сделать) не то, что Вы, как предполагается, делаете!

Я думаю, что ответ jano и ответ десерта делают точно, что Вы хотите, и у меня нет лучшего ответа. Но вот некоторые подсказки для отладки сценария...

test иначе [

Вы использовали [ который является встроенной оболочкой. Вы видите некоторую информацию об этом путем выполнения help [, но поскольку та информация говорит Вам, это - версия test команда и больше информации могут быть найдены под help test. Когда я запускаю Ваш скрипт (который я назвал script) Я получаю эти ошибки:

script: line 6: if[zanna == zanna]: command not found
script: line 7: syntax error near unexpected token `then'
script: line 7: `then'

Вам были нужны три пробелов для разделения if и [ команды от их аргументов. Кроме того, как Sergiy указал в комментарии, до версии 4.4 Bash, == оператор не существовал в test или [. Ubuntu 16.04 использует Bash 4.3. У меня есть Bash 4.4 в 17,10. Можно исправить синтаксическую ошибку как это:

if [ "$user" = "$name" ]

Вы, возможно, также постарались не присваивать дополнительную переменную путем создания того теста

if [ "$user" = "$(whoami)" ]

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

read

read Bash встроенная команда. Можно получить информацию о нем путем выполнения help read.

Когда Вы используете read команда, Вы, вероятно, хотите использовать -r опция предотвратить любые обратные косые черты во входе от действия как Escape.

Кроме того, а не echoлуг пользовательская подсказка, можно использовать read -p опция и запись подсказка после -p для более краткого сценария.

echo "Who are we checking on? "
read -r user

делает то же как

read -rp "Who are we checking on? " user

Вы также не должны строго называть переменную с тех пор read помещает вход в переменную REPLY автоматически. Можно протестировать это:

read -rp "Who are we checking on? "
echo "$REPLY"

Конечно, Вы часто хотите назвать переменную. Я думаю user был хороший выбор для этого.

if

if также встроенная оболочка, таким образом, можно узнать об этом путем выполнения help if. Вы будете видеть, что это проверяет команду после него и выполняется then перейдите, если статус выхода той команды был нулем (т.е. это было успешно). использование ответа jano if без test или [ путем простого сбора статуса выхода grep:

who -u | grep -q "^$user "

ищет вывод who -u видеть, запускается ли какая-либо строка со значения $user переменная. ^ запуск строки, и -q опция подавляет вывод. grepстатус выхода является нулем, если он находит соответствие, итак, если $user найден, then ответвление if структура будет выполняться, но если grep сбои для нахождения чего-либо, else ответвление if структура будет выполняться (если она будет существовать).

ответ десерта использует только логику оболочки для определения действий для успеха и отказа команды - даже if не необходимо здесь :)

test снова

Начиная с проверки статуса выхода достаточен, я не думаю, что Вам нужно [ или test команда вообще. Если Вы действительно хотите использовать его, Вы могли бы использовать что-то как

[ -n "$(w -h | grep "^$user ")" ]

Целая замена команды должна быть заключена в кавычки или [ будет жаловаться на слишком много аргументов, если будет несколько слов в выводе (так как $user будет одно слово, мы могли также использовать grep -o производить только соответствие). -n верно, если строка не пуста.

Альтернатива who -u w -h. Я не уверен, который является более портативным или надежным. Я заметил это who дает немного отличающийся вывод в различных эмуляторах терминала, хотя не достаточно отличающийся, чтобы мешать этому сценарию работать.

Заключение в кавычки

Большую часть времени Вы хотите заключить переменные в кавычки в сценариях для предотвращения дальнейших расширений. Утилиты, которые Вы используете для создания пользователей на Ubuntu, не позволят Вам создавать имя пользователя с пробелами или любыми другими символами, которые могли заставить оболочку выполнять расширение, таким образом, я не думаю, что строго важно заключить переменную в кавычки в этом сценарии. Однако, для таких имен пользователей возможно существовать, и это хорошая привычка заключить в кавычки переменные, которые не должны закрыться кавычки.


Для полноты вот моя версия без [ (это - по существу то же как janos'):

#!/bin/bash

read -rp "Who are we checking on? "
if w -h | grep -q "^$REPLY "; then
    echo "here's what "$REPLY" is doing:"
    top -u "$REPLY"
else
    echo "looks like "$REPLY" is not logged in."
fi
3
ответ дан 2 December 2019 в 01:29

То, что Вы просите, может на самом деле быть сделано с остротой:

read -p"Who are you? " u&&((who -u|grep -q "^$u "&&top -u"$u")||echo "$u is not logged in")

Но поскольку Вы запросили сценарий, вот намного более хорошая версия сценария:

#!/bin/bash
read -p "Who are you? " user && ((    # prompt for username, save as $user
who -u | grep -q "^$user "   &&       # test if user is logged in
top -u "$user"                   ) || # run top with that username
echo "$user is not logged in"   )     # error message

Объяснения

  • read -p "Who are you? " user – подсказка для имени пользователя и сохраняет его как переменную user
  • && – если это успешно, …
  • (…) – запустите подоболочку и сделайте в ней – если Вы не хотите запускать подоболочку, можно использовать { …;} вместо этого, пространство, а также точка с запятой обязательно
  • who -u | grep -q "^$user " – звонить who и grep для имени пользователя в начале строки (^) с предыдущим пространством (так, чтобы des не соответствует dessert)
  • top -u "$user" – выполненная вершина с именем пользователя
  • || – если это не успешно, т.е. если пользователь не зарегистрирован
  • echo "$u is not logged in" – распечатайте сообщение об ошибке

NB: которым Это может очень хорошо также быть, покончил if выражение как показано в других ответах. Я придерживался логических операторов и скобок здесь, потому что это - другой способ сделать его, и я хотел показать как.

3
ответ дан 2 December 2019 в 01:29

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

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