如何使用 crontab 从 shell 脚本启动屏幕会话然后重新附加到它?

如何使用 crontab 从 shell 脚本启动屏幕会话然后重新附加到它?

我想运行以下 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。

相关内容