![以用户名作为输入:如果用户已登录,则显示属于该用户的正在运行的进程](https://linux22.com/image/1152336/%E4%BB%A5%E7%94%A8%E6%88%B7%E5%90%8D%E4%BD%9C%E4%B8%BA%E8%BE%93%E5%85%A5%EF%BC%9A%E5%A6%82%E6%9E%9C%E7%94%A8%E6%88%B7%E5%B7%B2%E7%99%BB%E5%BD%95%EF%BC%8C%E5%88%99%E6%98%BE%E7%A4%BA%E5%B1%9E%E4%BA%8E%E8%AF%A5%E7%94%A8%E6%88%B7%E7%9A%84%E6%AD%A3%E5%9C%A8%E8%BF%90%E8%A1%8C%E7%9A%84%E8%BF%9B%E7%A8%8B.png)
我想编写一个脚本,将用户名作为命令行输入。如果该用户已登录,则它将显示该用户正在运行的进程。如果他/她未登录,则脚本应该提及这一点。
我的尝试没有奏效:
#!/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
答案1
您可以使用该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 | ...
部分!)
答案2
在我看来,你似乎对这个任务有些误解了。我猜这个脚本是系统管理员用来检查用户的东西,所以“你是谁?”,以及检查运行脚本的用户是否输入了自己的用户名(这是你的脚本试图做的)不是你应该做的!
我认为janos 的回答和甜点的答案按照你的要求做,我没有更好的答案。但这里有一些调试脚本的技巧...
test
又名[
您使用了[
shell 内置命令。您可以通过运行 查看有关它的一些信息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 在评论中指出的那样,直到 Bash 版本 4.4,或==
中不存在运算符。Ubuntu 16.04 使用的是 Bash 4.3。我在 17.10 中安装了 Bash 4.4。您可以像这样更正语法错误:test
[
if [ "$user" = "$name" ]
你也可以通过进行该测试来避免分配额外的变量
if [ "$user" = "$(whoami)" ]
但简洁并不一定意味着清晰,特别是在 shell 脚本中,此外,这不是你真正想做的事,因为运行脚本的用户必须登录才能运行脚本,所以即使是语法正确的脚本版本也只会检查用户是否正确输入了用户名,而这不是任务所要求的。
read
read
是 Bash 内置命令。您可以通过运行来获取有关它的信息help read
。
当您使用该read
命令时,您可能希望使用该-r
选项来防止输入中的任何反斜杠充当转义符。
此外,您可以使用的选项并在之后编写提示,而不是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
也是 shell 的内置命令,因此你可以通过运行来了解它help if
。你会看到它检查后面的命令并执行then
分支如果该命令的退出状态为零(即成功了)。janos 的回答使用if
而不test
或[
只是收集退出状态grep
:
who -u | grep -q "^$user "
搜索 的输出who -u
以查看是否有任何行以变量的值开头$user
。^
是行的开头,并且该-q
选项抑制输出。grep
如果找到匹配项,则 的退出状态为零,因此如果$user
找到,则将执行结构then
的分支,但如果找不到任何内容,则将执行结构的分支(如果存在)。if
grep
else
if
甜点的答案仅使用 shell 的逻辑来定义命令成功和失败的操作 -if
这里甚至没有必要:)
test
再次
由于检查退出状态就足够了,我认为你根本不需要[
或test
命令。如果你真的想使用它,你可以使用类似
[ -n "$(w -h | grep "^$user ")" ]
[
如果输出中有多个单词,则必须引用整个命令替换,否则会抱怨参数太多(因为$user
将是一个单词,我们也可以用来grep -o
仅输出匹配项)。-n
如果字符串不为空,则为真。
的替代方案who -u
是w -h
。我不确定哪个更便携或更可靠。我注意到who
在不同的终端仿真器中输出略有不同,但差异不足以阻止此脚本运行。
引用
大多数情况下,您需要在脚本中引用变量以防止进一步扩展。您在 Ubuntu 上用于创建用户的实用程序不允许您创建带有空格或任何其他可能导致 shell 执行扩展的字符的用户名,因此我认为在此脚本中引用变量并不是绝对必要的。不过,这样的用户名是有可能存在的,并且引用不需要取消引用的变量是一个好习惯。
为了完整起见,下面是我的版本,没有这个版本[
(它本质上与 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
你所要求的实际上可以用一行代码来完成:
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
&&
– 如果成功的话……(…)
– 启动一个子 shell 并…
在其中执行操作 – 如果你不想启动子 shell,可以使用{ …;}
以下命令:空格和分号都是必需的who -u | grep -q "^$user "
– 调用who
并grep
在行首 (^
) 处输入用户名,并在前面加一个空格(这样des
就不会匹配dessert
)top -u "$user"
– 使用用户名运行 top||
– 如果那是不是成功,即如果用户尚未登录echo "$u is not logged in"
– 打印错误信息
注意:这也可以很好地用表达式来实现,if
如其他答案所示。我在这里坚持使用逻辑运算符和括号,因为这是另一种方法,我想展示如何做到这一点。
答案4
echo "Enter Username: "
read check
_user="$(id -u -n)"
if [ "$check" = "$_user" ]
then
echo "User Logged In"
else
echo "User Not Logged In"
fi
这将完美地完成你的工作!