Я хочу написать скрипт, который принимает имя пользователя в качестве ввода командной строки. Если этот пользователь вошел в систему, он отобразит процессы, которые он выполняет. Если он / она не вошел в систему, то сценарий должен упомянуть об этом.
Моя попытка не работает:
#!/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
Можно использовать 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 | ...
часть!)
Мне похоже на недоразумение задачи немного. Я предполагаю, что сценарий - что-то, что системный администратор использовал бы для проверения пользователей, таким образом, "Кто Вы?", и проверка, что пользователь, запускающий скрипт, ввел их собственное имя пользователя (который является тем, что Ваш сценарий пытается сделать) не то, что Вы, как предполагается, делаете!
Я думаю, что ответ 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
То, что Вы просите, может на самом деле быть сделано с остротой:
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
выражение как показано в других ответах. Я придерживался логических операторов и скобок здесь, потому что это - другой способ сделать его, и я хотел показать как.