![如何使用 crontab 从 shell 脚本启动屏幕会话然后重新附加到它?](https://linux22.com/image/1492963/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20crontab%20%E4%BB%8E%20shell%20%E8%84%9A%E6%9C%AC%E5%90%AF%E5%8A%A8%E5%B1%8F%E5%B9%95%E4%BC%9A%E8%AF%9D%E7%84%B6%E5%90%8E%E9%87%8D%E6%96%B0%E9%99%84%E5%8A%A0%E5%88%B0%E5%AE%83%EF%BC%9F.png)
我想运行以下 shell 脚本 (launch.sh) 来使用 crontab 启动/停止屏幕会话
!/bin/bash
cd ~/screen
DATE_FORMAT=+%Y-%m-%d:%H:%M:%S
echo --- START ---
date $DATE_FORMAT
if [ -f ./screen.pid ]
then
PID="$(cat ./screen.pid)"
echo Stopping mitmproxy screen PID=$PID
kill $PID
rm ./screen.pid
fi
echo Rotating log files
logrotate -s ./logrotate.status ./logrotate.config
#Starting proxy in reverse mode
screen -S tty-mitmproxy -d -m mitmproxy -p 3333 -R http://localhost:8000 -a ./mitmproxy.log
if [ $? -eq 0 ]
then
PID="$(screen -ls | awk '/\.tty-mitmproxy\t/ {print strtonum($1)}')"
echo Starting mitmproxy screen PID=$PID
echo $PID > ./screen.pid
fi
date $DATE_FORMAT
echo --- END ---
exit 0
如果我通过 b 终端手动运行它
/home/fernando/screen/launch.sh >> /home/fernando/screen/launch.log 2>&1
它按预期工作
cat /home/fernando/screen/launch.log
输出(执行两次后)
--- START ---
2016-05-10:22:50:32
Rotating log files
Starting mitmproxy screen PID=4897
2016-05-10:22:50:32
--- END ---
--- START ---
2016-05-10:22:50:34
Stopping mitmproxy screen PID=4897
Rotating log files
Starting mitmproxy screen PID=4919
2016-05-10:22:50:34
--- END ---
在这种情况下,我可以通过 bash 终端正常重新连接到我的屏幕会话
screen -r
我想做同样的事情,但是通过 crontab 执行上述 shell 脚本
因此,我在用户的 crontab 中添加了以下行
*/10 * * * * /home/fernando/screen/launch.sh >> /home/fernando/screen/launch.log 2>&1
在预定时间之后,我尝试通过 bash 终端重新连接
screen -r
这次,我得到了回应
There is no screen to be resumed.
检查我的日志文件,我发现了这个奇怪的输出(由 crontab 执行两次后)
--- START ---
2016-05-10:23:00:01
Rotating log files
Starting mitmproxy screen PID=
2016-05-10:23:00:02
--- END ---
--- START ---
2016-05-10:23:10:01
Stopping mitmproxy screen PID=
kill: uso: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... ou kill -l [sigspec]
Rotating log files
Starting mitmproxy screen PID=
2016-05-10:23:10:01
--- END ---
我也搜索过系统日志
grep "launch.sh" /var/log/syslog
May 10 23:00:01 fernando-PC CRON[4992]: (fernando) CMD (/home/fernando/screen/launch.sh >> /home/fernando/screen/launch.log 2>&1)
May 10 23:10:01 fernando-PC CRON[5045]: (fernando) CMD (/home/fernando/screen/launch.sh >> /home/fernando/screen/launch.log 2>&1)
我究竟做错了什么?
附言:我在 Ubuntu 14.04 LTS 上运行,我的屏幕版本是 4.01.00devel (GNU) 2-May-06
编辑:
该问题似乎与我的 shell 脚本的以下行有关
screen -S tty-mitmproxy -d -m mitmproxy -p 3333 -R http://localhost:8000 -a ./mitmproxy.log
如果我以这种方式更改屏幕部分内执行的命令
screen -S tty-top -d -m top
有用!
答案1
看起来您的问题是$PID
未定义。您的“启动 mitmproxy 屏幕 PID”和“停止 mitmproxy 屏幕 PID”消息都没有定义 PID。kill
第一次从 cron 执行时没有出现错误launch.sh
,因为 PID 文件不存在并且“停止 mitmproxy”部分未执行。第二次调用时kill
未定义$PID
,因此出现错误。
cron 知道你的screen
和在哪里awk
吗?在确定 PID 的部分中是否需要使用绝对路径?
答案2
尝试使用 expect 包装对屏幕的调用。看起来 crontab 运行和终端运行之间的唯一区别是当您从 crontab 运行时没有 pty。expect 可以模拟 pty。