10

On macOs Catalina have problems with making screenshots over cron. When manually run do_screenshot.sh script then all fine. But when it run auto over cron - probs, only menu correct, instead window content shown macOs background(see pic)

do_screenshot.sh:

#!/bin/bash

DATEFULL=`date '+%Y%m%d%H%M%S'`
FILENAME="/Users/yak/Documents/screenshots/"$DATEFULL.png
/usr/sbin/screencapture -x $FILENAME

enter image description here

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
  • `man screencapture` says: "SECURITY CONSIDERATIONS To capture screen content while logged in via ssh, you must launch screencapture in the same mach bootstrap hierarchy as loginwindow: PID=pid of loginwindow sudo launchctl bsexec $PID screencapture [options]" – TheNextman Dec 09 '19 at 17:01
  • 2
    When I try that, I get: sudo launchctl bsexec 162 /usr/sbin/screencapture test.png > could not create image from display 0 -- any ideas? – Roman Gaufman Apr 04 '20 at 14:14

5 Answers5

10

Ran into this problem after the update too. Spent hours learning the details, here is the why and how. Credit goes to big-circle. The original question and answer here.

The problem is the cron doesn't have screen access.

Here's the solution

  1. close SIP (System Integrity Protection).

Make sure your SIP is disabled. To check if SIP is disabled. To to terminal and type csrutil status. It should say SIP status: enabled/disabled. To disable it:

Powerdown Mac, start up again and hold down cmd+r until OS X Utilities window shows up. Open terminal type csrutil disable. Restart again, boot into normal mac os.

  1. grant write permission to TCC

sudo chmod 664 /Library/Application\ Support/com.apple.TCC

  1. grant screencapure privilege to cron and screencapture

    a) CRON:

       `sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'insert into access values ("kTCCServiceScreenCapture", "/usr/sbin/cron", 1, 1, 1, "", "", "", "UNUSED", "", 0,"")'`
    

    b) screencapture:

       Pre Big Sur:
    `sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'insert into access values ("kTCCServiceScreenCapture", "/usr/sbin/screencapture", 1, 1, 1, "", "", "", "UNUSED", "", 0,"")'`
    

    --------------------------------------------------------------------------

       Big Sur and later:
    `sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'insert into access values ("kTCCServiceScreenCapture", "/usr/sbin/screencapture", 1,2,4,1, "", "", "", "UNUSED", "", 0,"")'`
    
  2. It's probably a good idea to turn SIP back on at this stage. To enable it, follow step 1, and instead of csrutil disable just type csrutil enable.

Edit @ 2021-12-09T11:58:00+1000: Added in commands for Big Sur and later per comment from Silvan Mühlemann

A Web-Developer
  • 868
  • 8
  • 29
  • For step 4, `csrutil clear` can be used instead to re-enable SIP without having to reboot into recovery on macOS Sierra 10.12.2 or later. – Matias Nov 04 '20 at 01:06
  • For Big Sur and later, the command has changed a bit. The following worked for me: `sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'insert into access values ("kTCCServiceScreenCapture", "/usr/sbin/screencapture", 1,2,4,1, "", "", "", "UNUSED", "", 0,"")'` Note the sequence `1,2,4,1`. Refer to https://rainforest.engineering/2021-02-09-macos-tcc/ for more details. – Silvan Mühlemann Dec 06 '21 at 06:09
2

You should allow your script to use the "Screen Recording" in the "Security & Privacy" system preferences.

  • yes, it added into "Screen Recording" as "Terminal"(MacOs detect screen capture and propose add). When i run script manually - all fine. Probs when script started by cron. – Aleksandr Yakushev Dec 10 '19 at 16:29
  • Did you ever find a solution to this? – Roman Gaufman Apr 04 '20 at 14:24
  • This is the simpler solution and worked for me for running the following script on the command line. (note: not cron) https://superuser.com/questions/676735/taking-screen-shot-from-mac-by-an-interval Thank you @Cary – watsonic Jun 06 '20 at 23:35
  • 1
    I tried the solution below with manipulating the TCC.db. This resulted in a broken TCC system. This solution worked perfectly. Note: I had to grant /sbin/cron (and not the script itself) the "Screen Recording" permissions. (Using Big Sur) – Silvan Mühlemann Dec 06 '20 at 17:46
  • Just give the /usr/sbin/cron "Screen Recording" and it works. – aisensiy Feb 10 '22 at 14:35
1
  1. You may start your app in a background from a terminal with a long loop (you need start it manually, that is not good):
#!/bin/bash
for value in {1..980}
do
/Users/<username>/record_activity_with_screen_capture.bash
sleep 60
done
echo All done

OR

use launchd (instead of cron) for running this script. There are two examples:

  1. how to start bash script in launchd
  2. How to add timing
  3. calendar example
1

Instead of playing with SIP (System Integrity Protection), which is dangerous, but suggested anyways but the top answer, simply give Screen Recording permissions to /usr/sbin/cron (or /sbin/cron in some MacOS versions I think).

In order to do that:

  1. Open System Settings
  2. Open Security & Privacy
  3. Go to the Privacy tab
  4. Go to Screen Recording
  5. Click the lock in the bottom left corner and authenticate in order to enable editing the list
  6. Now, if cron is listed there and unchecked, check it and the job is done. Likely is not listed there at all and you need to add it manually
  7. Click on + below the list of programs
  8. In the file picker hit a magic command Cmd+Shift+G, which will show a Go To Folder popup
  9. Type: /usr/sbin and hit Enter (if you can't find cron in the next steps, try /sbin here instead)
  10. You should see a list of files, all with an icon of a black terminal
  11. Find cron on the list and hit Open
  12. Check the checkbox next to cron
  13. Wait for your cron to run the command again.

Voila, it should be capturing screenshots now.

Lukasz Czerwinski
  • 13,499
  • 10
  • 55
  • 65
-2

You can try to change shebang to #!/bin/sh, or change screencapture to exec screencapture

Deni
  • 9