提问人:Alex 提问时间:10/9/2023 最后编辑:Alex 更新时间:10/21/2023 访问量:76
将 crontab 用于 awk 时输出不匹配
Output doesnt match when use crontab for awk
问:
我有一个用于服务器监控的脚本,当我运行手动使用时,该脚本工作正常。但是当我使用 crontab 运行它时,cron_status变量中还有一个额外的输出,即“awk”。但这只发生在主服务器(StorageEng)上,使用 ssh 远程的服务器不会遇到这种情况。这是我的脚本代码:./monitoring.sh
#!/bin/bash
## Scipt Monitoring Server
# Konfigurasi SQL
db_user="xx"
db_pass="xxxxx"
db_host="localhost"
db_name="Monitoring"
db_table="server"
# Function Query
query() {
local_query=$1
mysql --local-infile=1 -u "$db_user" -h "$db_host" "$db_name" -p"$db_pass" <<EOF
$local_query
EOF
}
# Konfigurasi penyimpanan csv
#USER=$(who | awk 'NR==1 {print $1}')
USER=$(whoami)
WORKDIR="/home/${USER}/Monitoring"
csv_file="${WORKDIR}/monitoring.csv"
# Mengecek apakah file CSV sudah ada, jika belum maka membuat header kolom
if [ ! -e "$csv_file" ]; then
echo "server_name,ip_address,cpu_usage,memory_used_mb,memory_capacity_mb,memory_free_mb,memory_shared_mb,memory_cache_mb,memory_available_mb,swap_capacity_mb,swap_used_mb,swap_free_mb,disk_used_gb,disk_free_gb,disk_capacity_gb,total_task,running_task,sleeping_task,stopped_task,rx_rate,tx_rate,total_rate,uptime,active_user,cron_status,date_time" > "$csv_file"
fi
# Menghapus semua data dari baris 2 sampai bawah dari file CSV
sed -i '2,$d' "$csv_file"
# INFOSERVER
server_name=$(hostname | awk '{print $1}')
server_ip=$(hostname -I | awk '{print $1}' )
## Mengambil Data
# CPU
cpu_usage=$(top -bn1 | awk '/Cpu/ {print $2}')
# MEMORY
memory_used=$(free --mega | awk '/Mem/{print $3}')
memory_capacity=$(free --mega | awk '/Mem/{print $2}')
memory_free=$(free --mega | awk '/Mem/{print $4}')
memory_shared=$(free --mega | awk '/Mem/{print $5}')
memory_cache=$(free --mega | awk '/Mem/{print $6}')
memory_available=$(free --mega | awk '/Mem/{print $7}')
# SWAP
swap_used=$(free --mega | awk '/Swap/{print $3}')
swap_capacity=$(free --mega | awk '/Swap/{print $2}')
swap_free=$(free --mega | awk '/Swap/{print $4}')
# DISK
disk_used=$(df -h | awk '/mapper/{gsub("G", "", $3); print $3}')
disk_free=$(df -h | awk '/mapper/{gsub("G", "", $4); print $4}')
disk_capacity=$(df -h | awk '/mapper/{gsub("G", "", $2); print $2}')
# PROCESS
total_task=$(top -bn1 | awk '/Tasks/{print $2}')
running_task=$(top -bn1 | awk '/Tasks/{print $4}')
sleeping_task=$(top -bn1 | awk '/Tasks/{print $6}')
stopped_task=$(top -bn1 | awk '/Tasks/{print $8}')
uptime=$(uptime -p | sed 's/,/;/g')
active_user=$(who | wc -l)
# Network
tx_rate=$(vnstat -5 1 | awk 'FNR == 7 {
if ($6 ~ /KiB/)
{
$5/=976.6;
}
else if ($5 ~ /MiB/)
{
$5*=1.048567;
}
printf("%.2f\n", $5);
}')
rx_rate=$(vnstat -5 1 | awk 'FNR == 7 {
if ($3 ~ /KiB/)
{
$2/=976.6;
}
else if ($3 ~ /MiB/)
{
$2*=1.048567;
}
printf("%.2f\n", $2);
}')
total_rate=$(vnstat -5 1 | awk 'FNR == 7 {
if ($9 ~ /KiB/)
{
$8/=976.6;
}
else if ($8 ~ /MiB/)
{
$8*=1.048567;
}
printf("%.2f\n", $8);
}')
# Cron Status
cron_status=$(systemctl status cron | awk '/Active/{print $2}')
# DATETIME
date_time=$(date "+%Y-%m-%d %H:%M:%S")
# Menambahkan data terbaru ke file CSV
echo "$server_name,$server_ip,$cpu_usage,$memory_used,$memory_capacity,$memory_free,$memory_shared,$memory_cache,$memory_available,$swap_capacity,$swap_used,$swap_free,$disk_used,$disk_free,$disk_capacity,$total_task,$running_task,$sleeping_task,$stopped_task,$rx_rate,$tx_rate,$total_rate,$uptime,$active_user,$cron_status,$date_time" >> "$csv_file"
for list in `cat ${WORKDIR}/list_server`
do
IPADDRESS=$(echo "${list}" | awk -F',' '{print $2}')
USER=$(echo "${list}" | awk -F',' '{print $3}')
ssh $USER@${IPADDRESS} "/usr/bin/bash /home/rizci/Monitoring/monitoring.sh"
ssh $USER@${IPADDRESS} "cat /home/rizci/Monitoring/monitoring.csv | sed '1d'" >> "$csv_file"
done
query "
LOAD DATA LOCAL INFILE '$csv_file'
INTO TABLE $db_table
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(server_name, ip_address, cpu_usage, memory_used_mb, memory_capacity_mb, memory_free_mb, memory_shared_mb, memory_cache_mb, memory_available_mb, swap_capacity_mb, swap_used_mb, swap_free_mb, disk_used_gb, disk_free_gb, disk_capacity_gb, total_task, running_task, sleeping_task, stopped_task, rx_rate, tx_rate, total_rate, uptime, active_user, cron_status, date_time);
"
# Menampilkan data di layar
echo "Berikut adalah data yang akan di-input:"
echo "Server Name : $server_name"
echo "Ip Address : $server_ip"
echo "Cpu Usage (%) : $cpu_usage"
echo "Memory Used (MB) : $memory_used"
echo "Memory Capacity (MB) : $memory_capacity"
echo "Memory Free (MB) : $memory_free"
echo "Memory Shared (MB) : $memory_shared"
echo "Memory Cache (MB) : $memory_cache"
echo "Memory Available (MB): $memory_available"
echo "Swap Capacity (MB) ; $swap_capacity"
echo "Swap Used (MB) : $swap_used"
echo "Swap Free (MB) : $swap_free"
echo "Disk Used (GB) : $disk_used"
echo "Disk Free (GB) : $disk_free"
echo "Disk Capacity (GB) : $disk_capacity"
echo "Total Task : $total_task"
echo "Running Task : $running_task"
echo "Sleeping Task : $sleeping_task"
echo "Stopped Task : $stopped_task"
echo "RX Rate (5 min) : $rx_rate"
echo "TX Rate (5 min) : $tx_rate"
echo "Total Rate (5 min) : $total_rate"
echo "Uptime : $uptime"
echo "Active User : $active_user"
echo "Cron Status : $cron_status"
echo "dateTime : $date_time"
以下是手动运行时监控 .csv 的输出:
server_name,ip_address,cpu_usage,memory_used_mb,memory_capacity_mb,memory_free_mb,memory_shared_mb,memory_cache_mb,memory_available_mb,swap_capacity_mb,swap_used_mb,swap_free_mb,disk_used_gb,disk_free_gb,disk_capacity_gb,total_task,running_task,sleeping_task,stopped_task,rx_rate,tx_rate,total_rate,uptime,active_user,cron_status,date_time
StorageEng,172.xx.xxx.xxx,0.0,919,2017,188,4,909,902,2147,66,2080,8.7,28,39,149,1,146,1,0.22,0.24,0.46,up 1 week; 6 days; 23 hours; 36 minutes,3,active,2023-10-09 11:19:16
ServerTesting,172.xx.xxx.xxx,0.0,355,2017,165,2,1496,1454,2147,8,2139,5.9,31,39,147,1,146,0,0.31,0.01,0.33,up 4 weeks; 3 days; 17 hours; 49 minutes,0,active,2023-10-09 11:19:16
DevOps,172.xx.xxx.xxx,0.0,607,2017,167,2,1242,1209,2147,250,1896,13,24,39,148,1,147,0,0.08,0.09,0.17,up 3 weeks; 4 days; 19 hours; 18 minutes,0,active,2023-10-09 11:19:18
这是使用 crontab 时的输出:
server_name,ip_address,cpu_usage,memory_used_mb,memory_capacity_mb,memory_free_mb,memory_shared_mb,memory_cache_mb,memory_available_mb,swap_capacity_mb,swap_used_mb,swap_free_mb,disk_used_gb,disk_free_gb,disk_capacity_gb,total_task,running_task,sleeping_task,stopped_task,rx_rate,tx_rate,total_rate,uptime,active_user,cron_status,date_time
StorageEng,172.17.30.182,1.6,922,2017,186,4,909,899,2147,66,2080,8.7,28,39,151,1,147,1,0.31,0.41,0.72,up 1 week; 6 days; 23 hours; 38 minutes,3,active
awk,2023-10-09 11:21:02
ServerTesting,172.17.30.183,0.0,352,2017,168,2,1496,1457,2147,8,2139,5.9,31,39,148,1,147,0,0.41,0.01,0.43,up 4 weeks; 3 days; 17 hours; 50 minutes,0,active,2023-10-09 11:21:03
DevOps,172.17.30.181,0.0,601,2017,172,2,1243,1215,2147,250,1896,13,24,39,148,1,147,0,0.08,0.09,0.16,up 3 weeks; 4 days; 19 hours; 20 minutes,0,active,2023-10-09 11:21:05
这是我的crontab -e:
GNU nano 6.2 /tmp/crontab.SNRQNh/crontab
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/1 * * * * /bin/bash /home/rizci/Monitoring/monitoring.sh
答:
答案可能与所使用命令的位置以及 cron 中使用的 PATH 有关。调用脚本的 Cron 传递的 PATH 字符串非常有限,因此脚本可能无法找到某些命令。大多数命令看起来非常标准,并且是 cron PATH 所涵盖的常用目录的一部分。但是“vnstat”和“mysql”在我看来是找不到的。
解决此问题的一种方法是确定任何“不寻常”命令(如“vnstat”)具有哪些路径目录。一种方法是:知道像这样的实用程序的路径,你可以在脚本的顶部添加一个。which vnstat
export PATH=$PATH:<whatever path you learned>
处理此问题的另一种方法是在命令行中显示当前路径,如下所示:echo $PATH
然后把整行都添加到脚本的顶部:export PATH=<< The entire Path you saw>>
看到回声时的示例:
echo $PATH
/usr/bin:/bin:/usr/local/bin:/some/other/bin
在此示例中,将以下内容添加到脚本中:export PATH=/usr/bin:/bin:/usr/local/bin:/some/other/bin
这将允许 cron 调用脚本并让脚本设置任何需要的 PATH 目录,以便脚本的其余部分可以找到命令。
评论
systemctl status cron | tee /tmp/debug.log | awk ...
free --mega
for
#!/usr/bin/env bash
#!/bin/bash