在mac中通过shell弹窗或发通知

Mac中有个AppleScript,通过它可以实现弹窗或系统通知

弹窗

osascript -e 'display alert "告警!!" as critical'
  • osascript -e 是执行一段apple script
  • display alert是弹窗
  • as critcal是用来控制图标,可以as三个值(informational,warning,critical,默认是informational)

发通知

osascript -e 'display notification "通知内容" with title "标题" subtitle "子标题" sound name "Glass"'
  • display notification 是发通知的命令后面紧跟着通知内容
  • with title 可以修改通知标题(默认是“脚本编辑器”)
  • subtitle 可以添加一个子标题(默认没有)
  • sound name 可以用来选择一种通知的声音,声音存放在/System/Library/Sounds

结合PHP实战

<?php
ini_set('date.timezone','PRC');

$host = 'mysql.example.org';
$port = '3306';
$dbname = 'test';
$username = 'root';
$password = '123456';
$pdo = new PDO("mysql:host={$host};port={$port};dbname={$dbname};charset=UTF8", $username, $password);

$sql = <<<SQL
SELECT u.uid, p.privilege_id, u.updated_at 
FROM user_privilege AS p 
LEFT JOIN user AS u ON u.uid = p.uid
WHERE u.del = 1 and p.del = 0;
SQL;

$statement = $pdo->query($sql);
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$new = [];

$logDir = __DIR__ . '/log/';
if (!file_exists($logDir)) {
    mkdir($logDir, 0755, true);
}
foreach ($result as $item) {
    $fileName = $logDir . '/' . $item['uid'] . '.json';
    if (!file_exists($fileName)) {
        file_put_contents($fileName, json_encode($item, JSON_PRETTY_PRINT));
        $new[] = $item['uid'];
    }
}
if ($new) {
    $msg = sprintf('%s发现新异常数据%d条!(%s)', date('Y-m-d H:i:s'), count($new), implode(', ', $new));
    $cmd = <<<CMD
osascript -e 'tell application "System Events" to display alert "{$msg}" as critical'
CMD;
    exec($cmd);
}

这个脚本连接一个远程的数据库,检查是否出现用户被删除,但是权限没有被删除的情况,如果发现将它记录到日志并弹窗提示。这里增加了tell application "System Events" to这么个前缀,是指以“System Events”这个应用弹这个窗,这是因为好像有什么机制会阻止cron任务中直接弹窗,需要借用另一个应用的身份。也可以借用”Finder”,发弹窗时Finder会跳动一下,但是弹窗需要点Finder才能出来,而使用System Event可以直接弹出来。

接下来可以在执行crontab -e来增加个计划任务

MAILTO=""
*/1 * * * * php ~/check.php > /dev/null
  • MAILTO=”” 是执行crontab不发执行结果的系统邮件
  • */1是指每1分钟执行一次,剩下的*分别代表:每小时(0~23)/每天(1~31)/每月(1~12)/每周几(0~6)