我正在开发一个包含一系列数据记录传感器的项目,这些传感器通过Java应用程序将所有数据发送回CSV文件。手动运行时,.jar文件和.sh文件都将打开应用程序并记录数据而不会出现问题。
此时,我需要每天早上6点重启程序,以便将CSV文件分段为1天的块。
以下是我使用的shell脚本示例:
#!/bin/bash
cd /home/pi/Desktop/Weights/410510/
sudo java -jar weight.jar
以下是我在Crontab中使用的内容:
0 6 * * * /home/pi/Desktop/./start410510 >/tmp/file_name.log 2>&1
我添加了日志文件输出以进行调试。程序将运行,有时甚至记录1个数据点,然后立即关闭。通过键盘上的用户干预或终端的物理出口手动关闭程序。 crontab是否可能输入导致程序关闭的内容?
这是程序中允许其关闭的部分:
System.out.print("\n\nPress any key to close...\n\n");
try {
System.in.read();
}
catch (IOException ex) {}
输出应该看起来像这样,但是整个24小时的数据点都是:
pi@raspberrypi ~/Desktop $ sudo java -jar weight.jar
Waiting for the Phidget Bridge to be attached...
Phidget Information
====================================
Version: 102
Name: Phidget Bridge 4-input
Serial #: 410510
# Bridges: 4
Setting the enable state of bridge 0 to true
Setting the gain of bridge 0 to 8
Setting the enable state of bridge 1 to true
Setting the gain of bridge 1 to 8
Setting the enable state of bridge 2 to true
Setting the gain of bridge 2 to 8
Setting the enable state of bridge 3 to true
Setting the gain of bridge 3 to 8
Setting the data rate to 1000
Press any key to close...
2015-08-27 11:39:29.05,1,7.6E-4
2015-08-27 11:39:29.252,2,0.002682
2015-08-27 11:39:29.46,3,-0.001937
2015-08-27 11:39:29.836,0,-5.36E-4
2015-08-27 11:39:30.044,1,8.2E-4
2015-08-27 11:39:30.252,2,0.002563
2015-08-27 11:39:30.468,3,-0.001922
2015-08-27 11:39:30.836,0,-4.77E-4
2015-08-27 11:39:31.044,1,7.3E-4
2015-08-27 11:39:31.252,2,0.002638
2015-08-27 11:39:31.468,3,-0.001952
2015-08-27 11:39:31.836,0,-4.32E-4
2015-08-27 11:39:32.044,1,7.3E-4
2015-08-27 11:39:32.252,2,0.002667
2015-08-27 11:39:32.468,3,-0.001878
2015-08-27 11:39:32.836,0,-4.92E-4
2015-08-27 11:39:33.044,1,6.41E-4
Turning off Phidget Bridge
相反,当程序通过Crontab运行时,日志文件的输出为:
pi@raspberrypi /tmp $ more file_name.log
Waiting for the Phidget Bridge to be attached...
Phidget Information
====================================
Version: 102
Name: Phidget Bridge 4-input
Serial #: 410510
# Bridges: 4
Setting the enable state of bridge 0 to true
Setting the gain of bridge 0 to 8
Setting the enable state of bridge 1 to true
Setting the gain of bridge 1 to 8
Setting the enable state of bridge 2 to true
Setting the gain of bridge 2 to 8
Setting the enable state of bridge 3 to true
Setting the gain of bridge 3 to 8
Setting the data rate to 1000
Press any key to close...
2015-08-27 09:16:03.086,2,-1.94E-4
Turning off Phidget Bridge
答案 0 :(得分:0)
以交互方式运行Java程序时,标准输入是控制台。如果用户未输入任何数据,则任何读取操作都会等待用户输入并被阻止。这是因为流打开,但还没有数据。
这意味着您可以使用标准输入(System.in
)的读取作为等待的方式。
但是当您在cron中运行程序时,非交互式System.in
标准输入不会绑定到控制台。它被绑定到一个零字节流(或者具有cron条目提供的某些信息的流,但目前无关紧要)。
当你有一个零字节流时,这意味着System.in.read()
不会等待。它立即返回值-1,表示已到达流结束。
这意味着如果您使用System.in.read()
在交互模式下等待,它将无法在非交互模式下工作。
当您从cron
运行作业时,您需要找到另一种方法来停止作业,并使用睡眠循环或其他等待机制使程序等到“停止”事件发生。
举一个简单的例子,如果你希望程序在工作一段时间后停止,比如8小时,你可以使用:
try {
Thread.sleep( 8L * 60L * 60L * 1000L ); // Sleep for 8 hours
} catch ( InterruptedException e ) {} // Interrupt means stop execution.
// ... code that cleans up and stops the program
请注意,告诉程序等待24小时并让cron在24小时后启动一个新程序可能不是一个好主意,因为旧执行和新执行很可能会有一个小的两个正在运行时的间隔(然后它们可能会争夺传感器),或 正在运行时的一小段时间(然后没有人正在听传感器。)< / p>
最好设计程序以使其无限期运行,并且有一个计时器每24小时滚动一次日志文件,而不是从cron运行它。