Verwenden Sie cron für die Bildschirmaufnahme unter Mac OS X.


7

Um meine eigene Computernutzung zu analysieren und niemanden auszuspionieren (obwohl es mir in den Sinn kam), möchte ich, dass Cron jede Minute den aktuellen Bildschirm erfasst.

 * * * * * /bin/bash -c "/usr/sbin/screencapture /somedir/screen.png"

in der crontab wird ausgeführt und eine Bildschirmaufnahme gemacht. Es ist jedoch total schwarz, weil es nicht so läuft wie ich. Haben Sie eine Idee, wie ein Cron-Job meinen Bildschirm erfassen kann?

Update: Ich say whoamihabe dem gleichen cron-Befehl einen hinzugefügt , der bestätigt, dass er als mein Benutzer ausgeführt wird (kein Sudo oder andere beteiligte Benutzer). Ich greife wie ich von einem Terminal aus auf die Crontab zu.

Es läuft also wie ich, ist aber nicht an mein Fenstersystem angeschlossen. Irgendwelche Ideen?


Fügen Sie dies Ihrer System- (Root-) Crontab oder Ihrer Benutzer-Crontab hinzu?
Richard Hoskins

Antworten:


10

Wenn Sie sich das Ende der Screencapture-Manpage ansehen, sehen Sie, dass dort steht:

Um Bildschirminhalte zu erfassen, während Sie über ssh angemeldet sind, müssen Sie starten
Bildschirmaufnahme in derselben Mach-Bootstrap-Hierarchie wie das Anmeldefenster:

PID = PID des Login-Fensters
sudo launchctl bsexec $ PID screencapture [Optionen]

Ich denke, Sie könnten so etwas in Ihrem Shell-Skript tun, das cron aufruft:

# / bin / sh
loginwindowpid = `ps axo pid, comm | grep '[l] oginwindow' | sed -ns # * \ ([^] * \). * $ # \ 1 # p'`
sudo launchctl bsexec $ loginwindowpid screencapture /somedir/screen.png

Natürlich muss Ihre Benutzer-ID so eingestellt sein, dass sie kein Passwort für sudo benötigt.
Das heißt, Sie würden in / etc / sudoers mit dem Befehl visudo einstellen

youruserid ALL = (ALL) NOPASSWD: ALL

Wunderbare Lösung für meine Frage. Sehr vollständig. Ich hatte die Manpage gelesen, same mach bootstrap hierarchyging aber direkt über meinen Kopf und ging direkt zu SU, um einen Sinn daraus zu machen. Vielen Dank.
Physikmichael

1
Sie können den Anruf an grep -vgrep [l]oginwindowcutps axo comm
beenden

Sehr schöne Lösung.
Laurent Etiemble

0

Wenn Sie ein anderes Konto sudoeinrichten cronmöchten, können Sie den -uSchalter zusammen mit verwenden sudo.

Beispiel:

sudo -u Your_user crontab -e

Andernfalls melden Sie sich einfach in diesem Konto an und verwenden Sie crontab -e.


0

Nebenbei benutze ich Java für den gleichen Job. Es beginnt beim Booten und ich schaue mir am Ende des Tages die Bilder an.

/**
 * Code modified from code given in http://whileonefork.blogspot.co.uk/2011/02/java-multi-monitor-screenshots.html following a SE question at  
 * http://stackoverflow.com/questions/10042086/screen-capture-in-java-not-capturing-whole-screen and then modified by a code review at http://codereview.stackexchange.com/questions/10783/java-screengrab
 */
package com.tmc.personal;

import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

class ScreenCapture {

    static int minsBetweenScreenshots = 5;

    public static void main(String args[]) {
        int indexOfPicture = 1000;// should be only used for naming file...
        while (true) {
            takeScreenshot("ScreenCapture" + indexOfPicture++);
            try {
                TimeUnit.MINUTES.sleep(minsBetweenScreenshots);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //from http://www.coderanch.com/t/409980/java/java/append-file-timestamp
    private  final static String getDateTime()
    {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd_hh:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("PST"));
        return df.format(new Date());
    }

    public static void takeScreenshot(String filename) {
        Rectangle allScreenBounds = getAllScreenBounds();
        Robot robot;
        try {
            robot = new Robot();
            BufferedImage screenShot = robot.createScreenCapture(allScreenBounds);
            ImageIO.write(screenShot, "jpg", new File(filename + getDateTime()+ ".jpg"));
        } catch (AWTException e) {
            System.err.println("Something went wrong starting the robot");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("Something went wrong writing files");
            e.printStackTrace();
        }
    }

    /**
     * Okay so all we have to do here is find the screen with the lowest x, the
     * screen with the lowest y, the screen with the higtest value of X+ width
     * and the screen with the highest value of Y+height
     * 
     * @return A rectangle that covers the all screens that might be nearby...
     */
    private static Rectangle getAllScreenBounds() {
        Rectangle allScreenBounds = new Rectangle();
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] screens = ge.getScreenDevices();

        int farx = 0;
        int fary = 0;
        for (GraphicsDevice screen : screens) {
            Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();
            // finding the one corner
            if (allScreenBounds.x > screenBounds.x) {
                allScreenBounds.x = screenBounds.x;
            }
            if (allScreenBounds.y > screenBounds.y) {
                allScreenBounds.y = screenBounds.y;
            }
            // finding the other corner
            if (farx < (screenBounds.x + screenBounds.width)) {
                farx = screenBounds.x + screenBounds.width;
            }
            if (fary < (screenBounds.y + screenBounds.height)) {
                fary = screenBounds.y + screenBounds.height;
            }
            allScreenBounds.width = farx - allScreenBounds.x;
            allScreenBounds.height = fary - allScreenBounds.y;
        }
        return allScreenBounds;
    }
}

Wichtige Syntaxfehler mit dem, was Sie gepostet haben
bafromca

Entschuldigung - Ich habe die fehlenden Klammern hinzugefügt ...
Joe

Am Ende fehlt noch eine geschweifte Klammer. Es öffnet die Klasse main (), while, try / catch und schließt dann try / catch, while, main (), schließt die Klasse jedoch nicht. Und dann fehlen auch die Importanweisungen oben. Dies ist, was ich am Ende hatte, nur um es zum Kompilieren zu bringen. Es ist noch nicht ausgeführt: pastebin.com/PrSfhUkS
bafromca

Ok - ich habe den vollständigen Code (auch avaible bei gegeben codereview.stackexchange.com/questions/10783/java-screengrab ) - kann ich Sie bitte , die Formatierung zu beheben? - Ich muss mich beeilen ...
Joe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.