我正在使用树莓派零通过
speedtest --csv
命令测试互联网速度。
我写了一个脚本,放在
/usr/local/bin/speedtest_script.sh
:
#!/bin/bash
# Define the file path for storing results
FILE_PATH="/home/marko/speedtest/speedtest_raspberrypi.csv"
# Run the speedtest and capture the results
SPEEDTEST_RESULT=$(speedtest --csv)
# Check if the CSV file exists; if not, create the header
if [ ! -f "$FILE_PATH" ]; then
echo "Date,Time,Ping (ms),Download,Upload,Location,Distance" > "$FILE_PATH"
fi
# Extract and format the data from the `speedtest` output
DATE=$(date '+%Y/%m/%d')
TIME=$(date '+%H:%M:%S')
PING=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $6}')
DOWNLOAD=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $7}')
UPLOAD=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $8}')
LOCATION=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $3}')
DISTANCE=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $5}')
# Append the formatted results to the CSV file
echo "$DATE,$TIME,$PING,$DOWNLOAD,$UPLOAD,$LOCATION,$DISTANCE" >> "$FILE_PATH"
已使用命令
speedtest_script.sh
和 sudo chmod +x speedtest_script.sh
将文件 sudo chmod +w speedtest_script.sh
制作为可执行文件,并授予其读写权限。
有了这个背景,这就是我面临的问题:
如代码所示,脚本应该在
speedtest_raspberrypi.csv
中生成文件 /home/marko/speedtest/speedtest_raspberrypi.csv
。当我手动运行命令speedtest_script.sh
时,它执行得很好。但是,作为 cron 作业的一部分,我只能获取日期和时间,而不能获取其他相关信息。
speedtest_raspberrypi.csv 的片段如下:
Date,Time,Ping (ms),Download,Upload,Location,Distance
2023/10/29,14:35:10,28.941,33661436.554366775,12456063.667141322,MyCity,196.5378436042561
2023/10/29,14:45:02,,,,,
第一行结果是我手动执行命令时生成的。 第二行结果是作为 cron 作业的一部分生成的。
这是我在
crontab -e
中写的内容:
# m h dom mon dow command
*/15 * * * * speedtest_script.sh
为什么我的脚本在手动运行时会生成正确的输出,但在作为 cronjob 的一部分时却不会?
首先我认为你有一个误解 -
sudo chmod +w speedtest_script.sh
不授予脚本读写权限。相反,它为所有类别的用户授予“该文件”的写入权限。这意味着执行命令后,任何用户都可以修改speedtest_script.sh
脚本本身。即您不是授予用户“读写权限”,而是授予用户写入权限。
其次,回答您的问题“为什么我的脚本在手动运行时会生成正确的输出,但在作为 cronjob 的一部分时却不会?” - 我猜你的问题是 cron 作业没有与用户相同的 PATH
环境变量。因此,如果 cron 作业的默认
speedtest
中没有找到
PATH
,则该命令将无法执行。因此您看不到任何数据。要解决此问题,只需确保您的脚本明确设置了正确的 speedtest
路径即可。例如
运行命令
which speedtest
它应该输出类似
/usr/bin/speedtest
的内容
然后只需在脚本中使用该绝对路径,例如
#!/bin/bash
# Define the file path for storing results
FILE_PATH="/home/marko/speedtest/speedtest_raspberrypi.csv"
# Run the speedtest and capture the results using the absolute path
# for example...
SPEEDTEST_RESULT=$(/usr/bin/speedtest --csv)
# Check if the CSV file exists; if not, create the header
if [ ! -f "$FILE_PATH" ]; then
echo "Date,Time,Ping (ms),Download,Upload,Location,Distance" > "$FILE_PATH"
fi
# Extract and format the data from the `speedtest` output
DATE=$(date '+%Y/%m/%d')
TIME=$(date '+%H:%M:%S')
PING=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $6}')
DOWNLOAD=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $7}')
UPLOAD=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $8}')
LOCATION=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $3}')
DISTANCE=$(echo "$SPEEDTEST_RESULT" | awk -F ',' '{print $5}')
# Append the formatted results to the CSV file
echo "$DATE,$TIME,$PING,$DOWNLOAD,$UPLOAD,$LOCATION,$DISTANCE" >> "$FILE_PATH"