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

3424
physicsmichael

Um meine eigene Computernutzung zu analysieren, um niemanden auszuspähen (obwohl mir das einfällt), möchte ich, dass Cron den aktuellen Bildschirm jede Minute 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 gut läuft wie ich. Irgendeine Idee, wie man einem Cron-Job erlaubt, meinen Bildschirm zu erfassen?

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

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

7
Fügen Sie dies Ihrem System (Root) Crontab oder Ihrem Benutzer Crontab hinzu? Richard Hoskins vor 15 Jahren 0

3 Antworten auf die Frage

10
todbot

Wenn Sie am Ende der screencapture-Manpage nachsehen, wird Folgendes angezeigt:

Um Bildschirminhalte zu erfassen, während Sie über ssh angemeldet sind, müssen Sie starten screencapture in derselben mach-Bootstrap-Hierarchie wie loginwindow:  PID = PID des Anmeldefensters sudo launchctl bsexec $ PID screencapture [Optionen] 

Ich denke, Sie könnten so etwas in Ihrem Shellskript machen, das von cron aufgerufen wird:

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

Natürlich benötigen Sie Ihre Benutzer-ID, um kein Kennwort für sudo zu benötigen.
Das heißt, Sie hätten mit dem Befehl visudo in / etc / sudoers festgelegt

youruserid ALL = (ALL) NOPASSWD: ALL 
Wunderbare Lösung für meine Frage. Sehr komplett Ich hatte die Manpage gelesen, aber "gleiche Mach-Bootstrap-Hierarchie" ging direkt über meinen Kopf, also ging ich direkt in die SU, um mir einen Eindruck davon zu verschaffen. Vielen Dank. physicsmichael vor 15 Jahren 0
Sie können den Aufruf von "grep -v" aufheben, indem Sie den ersten Anruf wie "grep [l] oginwindow" aussehen lassen und möglicherweise den Aufruf von "cut" mit "ps axo comm" aufheben Dennis Williamson vor 15 Jahren 1
Sehr schöne Lösung Laurent Etiemble vor 14 Jahren 0
0
John T

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

Beispiel:

sudo -u Your_user crontab -e 

Ansonsten loggen Sie sich einfach in dieses Konto ein und verwenden Sie es crontab -e.

0
Joe

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

/** * 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 bei dem, was Sie geschrieben haben bafromca vor 11 Jahren 0
Entschuldigung - ich habe die fehlenden Klammern hinzugefügt ... Joe vor 11 Jahren 0
Am Ende fehlt noch eine weitere geschweifte Klammer. Es öffnet die Klasse main (), while, try / catch und schließt dann try / catch, while, main (), schließt jedoch die Klasse nicht. Und dann fehlen auch seine Import-Anweisungen an der Spitze. Dies ist, was ich endete, nur um es zu kompilieren. Es läuft immer noch nicht: http://pastebin.com/PrSfhUkS bafromca vor 11 Jahren 0
Okay - Ich habe den vollständigen Code gegeben (auch verfügbar unter http://codereview.stackexchange.com/questions/10783/java-screengrab) - kann ich Sie bitten, die Formatierung zu korrigieren? - Ich muss loslaufen ... Joe vor 11 Jahren 0