当脚本读取文本文件时,我希望此代码在特定变量中找到特定字符串时运行特定命令。
例子:
假设我想使用以下代码来读取命令的输出last
:
#!/bin/bash
for i in `last`; do
sleep 0.1 | echo -ne "$i "
done
该命令的输出last
是一个条目列表形式的表,类似于:
username pts/2 1.2.3.4 via Sun Sep 2 06:40 - 06:40 (00:00)
. . . .
. . . .
i
前面代码中的变量可以是上表中的任何短语。我想应用一个特定的命令,例如开始新行当代码在变量中找到特定字符串时i
,例如当变量i
包含闭括号时)
,我希望代码开始新行。当代码完成读取命令的输出时
last
,我希望代码重复为了再次循环(多次)以读取是否有任何新的更新。如何指示代码再次重新运行?例如,是否有这样的命令goto
可以强制代码转到特定行?
请您给点建议吗?
答案1
如果你的输出last
是这样的:
username pts/2 1.2.3.4 via Sun Sep 2 06:40 - 06:40 (00:00)
并且您想在原来的位置添加换行符,那么我建议稍微改变一下逻辑。首先逐行读取输入,然后才将行拆分为单词。这样,就无需明确查找括号。您可以通过将其包装在 中来重复整个循环while true; do ... done
。所以我们有这样的内容:
#!/bin/bash
set -f
while true; do
last | while IFS= read -r line; do
for word in $line; do
sleep .1
printf "%s " "$word"
done
echo # prints a newline
done
done
set -f
禁用文件名扩展,否则可能会在未加引号的扩展中发生$line
。另外,printf
出于多种原因,我会使用echo 而不是 echo 来打印单词。
如果您确实想要查找右括号,那么您可以使用该[[ .. ]]
测试:它允许与类似 glob 的模式或正则表达式进行模式匹配。 ([[ $word =~ $re ]]
将是正则表达式匹配)
#!/bin/bash
set -f
while true; do
for word in $(last); do
sleep .1
printf "%s " "$word"
[[ $word = *')'* ]] && echo
done
done
当然,尽管这一行不会在最终登录持续时间被替换为 之类的行上添加换行符still logged in
。
该for word in $whatever
结构的缺点是它对待多个空格就像对待单个空格一样,因此脚本的输出不会像原始那样将列整齐地对齐。
答案2
您可以使用if .. then
类似以下的语句:
#!/bin/bash
for i in `last`; do
sleep 0.1 | echo -ne "$i "
if [[ $i = *')'* ]] ; then
echo "" ;
fi
done
如果您想for loop
在 bash 中重复读取命令的输出(在您的示例中为 command last
),那么您必须将脚本安排在crontab
.更多澄清是这里。
答案3
您可以采用不同的方法,我们需要您描述您的需求(识别特定人员的登录?识别谁在特定时间登录?等等)
正如您所说(当最后出现某些内容时添加换行符),您已经有了不同的方法:
#finding if a 'last' line contains a "specific_thing" (which is itself a regular expression...)
# and can print all lines or not depending on showall value
while true ; do
last | awk -v looking_for="specific_thing" -v showall=0 '
( showall == 1 ) { print $0 }
( $0 ~ looking_for ) { action="print line? and add something to it?" }
'
done
#watch for new things appearing in last and not the whole "last" output every time
watch last | awk -v looking_for="specific_thing" -v showall=0 '
( showall == 1 ) { print $0 }
( $0 ~ looking_for ) { action="print the line? with added infos?"
action="execute : system(some command) ?"
action="all of that?" }
'
ETC。
您还可以在日志文件中查找幽灵
您还可以在 /etc/profile 中插入一些命令(请注意,它可能会产生很多安全隐患,并且还可能在启动、初始化启动等时产生问题。这将是一个丑陋的黑客行为,可能会造成几个(或全部)用户的登录,无论如何都可以通过登录者快速按下 ctrl-C 来绕过...)
等等。有很多方法可以走,最好的方法就是修复你需要做的事情,现在必须坚持“最后”和“当我看到其中的内容时添加换行符”
为了获得更好的答案,请告诉我们您真正需要什么,以及您为什么需要它,而不是您认为您需要如何执行此或该操作(当您看到最后一个输出时添加换行符?您为什么认为您需要这样做的根本需求是什么?)