如何在脚本中停止 tail 命令
How do I stop tail command in script
我想做的事 - 开始使用自定义 ssh 客户端代码将更改捕获到日志文件***。一段时间后(这不是固定值并且是基于事件的),发出停止拖尾的命令。这是我用来捕获日志文件的最新更改的命令 - tail -f logfile.txt
我希望能够以 :q
之类的东西结束它,我可以从脚本发出它。我不想输入 ctrl + c
.
这样的键盘命令
*** 我的自定义 ssh 客户端代码的伪代码(用 oop 语言编写)
include ssh-api
ssh = getSSHConnection();
cmd = 'cd to folder';
ssh.command(cmd);
cmd = 'tail -f log.txt';
ssh.command(cmd);
wait for special event to occur...
cmd = 'stop the tail now!'
out = ssh.command(cmd);
print "the changes made to log file were\n" + out;
我对日志文件所在的服务器没有写入权限。
我试过的 - http://www.linuxquestions.org/questions/red-hat-31/how-to-stop-tail-f-in-scipt-529419/
我无法理解那里的解决方案(在 post 2 中)。有人可以解释解决方案或建议不同的方法吗?
谢谢。
在您的脚本中,您可以使用 $!
变量。
# run tail -f in background
tail -f /var/log/sample.log > out 2>&1 &
# process id of tail command
tailpid=$!
# wait for sometime
sleep 10
# now kill the tail process
kill $tailpid
$!
扩展为最近执行的后台(异步)命令的进程 ID。
您所指的 post#2 执行以下操作:有正确答案。
它说:
tail -f /etc/httpd/logs/access_log & # This starts tailing the file in background (see & at the end)
kill `ps | grep tail | awk '{print ;}'` # This finds the process running above tail command and kills it
您可能需要引入 sleep 100
或其他内容,具体取决于您的需要,否则,上述两个命令将导致拖尾只是一小部分时间,然后再将其杀死。
您可以在后台执行 tail,同时将其输出重定向到另一个文件(例如 /tmp/mylog
),并将进程的 pid 写入 pid 文件中的某处(例如 ~/mytail.pid
):
tail -f logfile > /tmp/mylog & echo $! > ~/mytail.pid
接下来,当你想停止它的时候,只要执行:
kill `cat ~/mytail.pid`
然后,你可以看到你同时收集的日志内容(稍后删除它也是一个好主意):
cat /tmp/mylog
rm /tmp/mylog # just don't forget it there
根据您对@psmears 的评论,您可能会使用 CTRL+C
@psmears - surely. that would work too. All I want to do is tell unix to tail a file, stop tailing it whenever I want, and get me the output between starting and ending the tailing. Thanks. – Borat Sagdiyev 2 days ago
因此您可以简单地在 ssh 参数中启动您的命令。
ssh username@remotehost tail -f /var/log/remotelog.txt | tee result.log
完成后,点击 CTRL+C
在前面的命令中,我使用了 tee
命令,以便在我的终端中查看新行并将它们存储到文件中。
如果您希望它是可编写脚本的
您可以执行以下操作:
## store result to file
FILE=result.log
## launch tail remote log, and store result to result.log
ssh -n username@remote-host tail -f /path/to/remote.log > $FILE &
## store pid
SSHPID=$!
## wait for ":q" command
while [ "$cmd" != ":q" ]; do
echo -ne "\n$ "
read -n 2 cmd
done
## kill ssh when you've enough
kill $SSHPID
## read result
echo "the changes made to log file were\n"
cat $FILE
请注意,如果您想要将启动和停止脚本分开,您只需将 SSHPID 存储在脚本中的一个文件中
echo $SSHPID > ~/.sshpid
并从第二个中检索它
SSHPID=`cat ~/.sshpid`
我用来解决 tail -f
的一些方法,使用 bash。
等待具体的通知:
我经常用这个:
sed -une '
/DHCPOFFER/{
s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/ -> /p;
q;
}' < <(
tail -f /var/log/syslog
)
使用此命令,我可以等待下一个 dhcp 客户端 并获取事件时间、mac 地址和提供的 IP。
在脚本中:
#!/bin/bash
read rMac rIp rDate < <(
sed -une '
/DHCPOFFER/{
s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/ /p;
q;
}' < <(
tail -n0 -f /var/log/syslog
))
printf "Date:\t%s\nMac:\t%s\nIP:\t%s\n" "$rDate" $rMac $rIp
远程停止脚本:
先进先出方式:
mkfifo /tmp/holder
tail -f /var/log/syslog &
TailPid=$!
cat >/dev/null /tmp/holder
kill -9 $TailPid
...然后从其他地方:
echo >/tmp/holder
将终止 tail 命令。
lockpid方式
#!/bin/bash
[ -e /tmp/lockfile ] && exit
echo $$ >/tmp/lockfile
[ $(</tmp/lockfile) -ne $$ ] && exit
cd /var/log
tail -f syslog &
export tPid=$!
trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
wait $tPid
然后,从其他地方:
kill -USR2 $(</tmp/lockfile)
通过 SSH
第二种方法通过 ssh 工作正常:
ssh -T root@remoteMachine /bin/bash <<"eocmd"
[ -e /tmp/lockfile ] && exit
echo $$ >/tmp/lockfile
[ $(</tmp/lockfile) -ne $$ ] && exit
cd /var/log
tail -f syslog &
export tPid=$!
trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
wait $tPid
eocmd
(注意内联脚本标签周围的双引号)
然后,从其他地方:
ssh root@remoteMachine '/bin/bash -c "kill -USR2 $(</tmp/lockfile)"'
(关心引号和双引号,按顺序)
安全注意事项:这里不考虑安全问题!在 /tmp
中放置这种 lockfile 可能不是一个好主意...
让 tail 正确退出比 kill 更好:
tail -n0 --pid=$(($BASHPID+1)) -F logfile | sed '/special event string in the log/q'
管道时,PID 是连续的,所以 tail 的 pid 将为 $BASHPID,sed 的 pid 将为 $BASHPID+1。 --pid 开关将导致 tail 在 sed 命令退出时退出(正确地!)。显然这是一个bashism。
我想做的事 - 开始使用自定义 ssh 客户端代码将更改捕获到日志文件***。一段时间后(这不是固定值并且是基于事件的),发出停止拖尾的命令。这是我用来捕获日志文件的最新更改的命令 - tail -f logfile.txt
我希望能够以 :q
之类的东西结束它,我可以从脚本发出它。我不想输入 ctrl + c
.
*** 我的自定义 ssh 客户端代码的伪代码(用 oop 语言编写)
include ssh-api
ssh = getSSHConnection();
cmd = 'cd to folder';
ssh.command(cmd);
cmd = 'tail -f log.txt';
ssh.command(cmd);
wait for special event to occur...
cmd = 'stop the tail now!'
out = ssh.command(cmd);
print "the changes made to log file were\n" + out;
我对日志文件所在的服务器没有写入权限。
我试过的 - http://www.linuxquestions.org/questions/red-hat-31/how-to-stop-tail-f-in-scipt-529419/
我无法理解那里的解决方案(在 post 2 中)。有人可以解释解决方案或建议不同的方法吗?
谢谢。
在您的脚本中,您可以使用 $!
变量。
# run tail -f in background
tail -f /var/log/sample.log > out 2>&1 &
# process id of tail command
tailpid=$!
# wait for sometime
sleep 10
# now kill the tail process
kill $tailpid
$!
扩展为最近执行的后台(异步)命令的进程 ID。
您所指的 post#2 执行以下操作:有正确答案。
它说:
tail -f /etc/httpd/logs/access_log & # This starts tailing the file in background (see & at the end)
kill `ps | grep tail | awk '{print ;}'` # This finds the process running above tail command and kills it
您可能需要引入 sleep 100
或其他内容,具体取决于您的需要,否则,上述两个命令将导致拖尾只是一小部分时间,然后再将其杀死。
您可以在后台执行 tail,同时将其输出重定向到另一个文件(例如 /tmp/mylog
),并将进程的 pid 写入 pid 文件中的某处(例如 ~/mytail.pid
):
tail -f logfile > /tmp/mylog & echo $! > ~/mytail.pid
接下来,当你想停止它的时候,只要执行:
kill `cat ~/mytail.pid`
然后,你可以看到你同时收集的日志内容(稍后删除它也是一个好主意):
cat /tmp/mylog
rm /tmp/mylog # just don't forget it there
根据您对@psmears 的评论,您可能会使用 CTRL+C
@psmears - surely. that would work too. All I want to do is tell unix to tail a file, stop tailing it whenever I want, and get me the output between starting and ending the tailing. Thanks. – Borat Sagdiyev 2 days ago
因此您可以简单地在 ssh 参数中启动您的命令。
ssh username@remotehost tail -f /var/log/remotelog.txt | tee result.log
完成后,点击 CTRL+C
在前面的命令中,我使用了 tee
命令,以便在我的终端中查看新行并将它们存储到文件中。
如果您希望它是可编写脚本的
您可以执行以下操作:
## store result to file
FILE=result.log
## launch tail remote log, and store result to result.log
ssh -n username@remote-host tail -f /path/to/remote.log > $FILE &
## store pid
SSHPID=$!
## wait for ":q" command
while [ "$cmd" != ":q" ]; do
echo -ne "\n$ "
read -n 2 cmd
done
## kill ssh when you've enough
kill $SSHPID
## read result
echo "the changes made to log file were\n"
cat $FILE
请注意,如果您想要将启动和停止脚本分开,您只需将 SSHPID 存储在脚本中的一个文件中
echo $SSHPID > ~/.sshpid
并从第二个中检索它
SSHPID=`cat ~/.sshpid`
我用来解决 tail -f
的一些方法,使用 bash。
等待具体的通知:
我经常用这个:
sed -une '
/DHCPOFFER/{
s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/ -> /p;
q;
}' < <(
tail -f /var/log/syslog
)
使用此命令,我可以等待下一个 dhcp 客户端 并获取事件时间、mac 地址和提供的 IP。
在脚本中:
#!/bin/bash
read rMac rIp rDate < <(
sed -une '
/DHCPOFFER/{
s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/ /p;
q;
}' < <(
tail -n0 -f /var/log/syslog
))
printf "Date:\t%s\nMac:\t%s\nIP:\t%s\n" "$rDate" $rMac $rIp
远程停止脚本:
先进先出方式:
mkfifo /tmp/holder
tail -f /var/log/syslog &
TailPid=$!
cat >/dev/null /tmp/holder
kill -9 $TailPid
...然后从其他地方:
echo >/tmp/holder
将终止 tail 命令。
lockpid方式
#!/bin/bash
[ -e /tmp/lockfile ] && exit
echo $$ >/tmp/lockfile
[ $(</tmp/lockfile) -ne $$ ] && exit
cd /var/log
tail -f syslog &
export tPid=$!
trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
wait $tPid
然后,从其他地方:
kill -USR2 $(</tmp/lockfile)
通过 SSH
第二种方法通过 ssh 工作正常:
ssh -T root@remoteMachine /bin/bash <<"eocmd"
[ -e /tmp/lockfile ] && exit
echo $$ >/tmp/lockfile
[ $(</tmp/lockfile) -ne $$ ] && exit
cd /var/log
tail -f syslog &
export tPid=$!
trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
wait $tPid
eocmd
(注意内联脚本标签周围的双引号)
然后,从其他地方:
ssh root@remoteMachine '/bin/bash -c "kill -USR2 $(</tmp/lockfile)"'
(关心引号和双引号,按顺序)
安全注意事项:这里不考虑安全问题!在 /tmp
中放置这种 lockfile 可能不是一个好主意...
让 tail 正确退出比 kill 更好:
tail -n0 --pid=$(($BASHPID+1)) -F logfile | sed '/special event string in the log/q'
管道时,PID 是连续的,所以 tail 的 pid 将为 $BASHPID,sed 的 pid 将为 $BASHPID+1。 --pid 开关将导致 tail 在 sed 命令退出时退出(正确地!)。显然这是一个bashism。