将 crontab 用于 awk 时输出不匹配

Output doesnt match when use crontab for awk

提问人:Alex 提问时间:10/9/2023 最后编辑:Alex 更新时间:10/21/2023 访问量:76

问:

我有一个用于服务器监控的脚本,当我运行手动使用时,该脚本工作正常。但是当我使用 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


Linux Bash Shell Ubuntu AWK

评论

0赞 tink 10/9/2023
你的crontab条目是什么样子的?
0赞 jhnc 10/9/2023
尝试保存整个输出(例如)并检查内容systemctl status cron | tee /tmp/debug.log | awk ...
1赞 Ed Morton 10/10/2023
您的脚本有很多问题,例如在输出中调用 awk 9 次而不是最多一次,变量的大小写错误,未带引号的变量,循环反模式等,因此您可能需要提出一些新问题,以帮助您完成您正在尝试做的各种事情,但对于您当前的问题 - 您可能正在终端中运行 bash,而 cron 正在运行 sh,因此在顶部,以便它始终在同一个 shell 中运行。free --megafor#!/usr/bin/env bash
0赞 Diego Torres Milano 10/10/2023
shellcheck.net 开始
0赞 Alex 10/10/2023
@EdMorton对不起,我已经输入了我的脚本,但忘记在我的问题上添加它#!/bin/bash

答:

0赞 Crispin Bivans 10/21/2023 #1

答案可能与所使用命令的位置以及 cron 中使用的 PATH 有关。调用脚本的 Cron 传递的 PATH 字符串非常有限,因此脚本可能无法找到某些命令。大多数命令看起来非常标准,并且是 cron PATH 所涵盖的常用目录的一部分。但是“vnstat”和“mysql”在我看来是找不到的。

解决此问题的一种方法是确定任何“不寻常”命令(如“vnstat”)具有哪些路径目录。一种方法是:知道像这样的实用程序的路径,你可以在脚本的顶部添加一个。which vnstatexport 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 目录,以便脚本的其余部分可以找到命令。