I have a script that runs an Intel app stored inside it. The script fails if it runs on an M1 Mac that doesn’t have Rosetta 2 installed. Is there a way that the script can test whether Rosetta 2 is installed and prompt the user to install it if it isn’t?
I can’t find any answer to this online, but maybe I haven’t looked attentively enough. Thanks for any advice.
EDIT: I looked more attentively and found this but (EDIT2) it seems to fail on the Monterey beta: It reinstalls Rosetta 2 on a system that already has it installed, and then, if run a second time, it reports an error “Package reference com.apple.pkg.RosettaUpdateAuto is missing installKBytes attribute.” Possibly the author will update it before long.
I set up a test volume with Rosetta not installed. Your script correctly reported that it wasn’t installed there, and correctly reported that it’s installed in my working system. Thank you!
Great! I was trying to figure out if I can install M1 version of Big Sur in VMWare, but it doesn’t seem possible, because VMWare itself is Intel, but I’m not 100% sure.
I know this going off-topic, but you may be able to install M1 Big Sur in Parallels Desktop, which is now a universal app and runs the ARM version of Windows 10.
EDIT: Parallels doesn’t support macOS on M1 machines. There’s something called UTM out there, but it’s reported very slow. So there seems to be no way to install a guest macOS system on an M1 Mac, at least now.
I think this may do the job of testing for Rosetta 2 and installing if needed:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set ss to "processor=$(/usr/sbin/sysctl -n machdep.cpu.brand_string | grep -o \"Intel\")
if [[ -n \"$processor\" ]]; then
echo 'intel'
else
if [[ \"`pkgutil --files com.apple.pkg.RosettaUpdateAuto`\" == \"\" ]]
then
echo 'not-present'
else
echo 'installed'
fi
fi"
set rosetta to do shell script ss
if rosetta is "not-present" then
try
do shell script "/usr/sbin/softwareupdate --install-rosetta"
on error err
display dialog err
end try
end if
Actually that script doesn’t work correctly, and neither does this revised version, for reasons I’ll describe below:
on checkRosetta()
set ss to "processor=$(/usr/sbin/sysctl -n machdep.cpu.brand_string | grep -o \"Intel\")
if [[ -n \"$processor\" ]]; then
echo 'intel'
else
if [[ \"`pkgutil --files com.apple.pkg.RosettaUpdateAuto`\" == \"\" ]]
then
echo 'not-present'
else
echo 'installed'
fi
fi"
set rosetta to do shell script ss
if rosetta is "not-present" then
display dialog "Rosetta 2 needs to be installed before I can run. Shall I continue?" buttons {"OK", "Cancel"} with title "Rosetta 2 required" default button 1
if button returned of result is "Cancel" then
error number -128
end if
try
do shell script "sudo /usr/sbin/softwareupdate --install-rosetta –agree-to-license" with administrator privileges
on error err
display dialog err
end try
end if
end checkRosetta
What goes wrong here is that a dialog box pops up saying: I have read and agree to the terms of the software license agreement. A list of Apple SLAs may be found here: http://www.apple.com/legal/sla/ Type A and press return to agree:
This is the same message that appears when entering the command at the terminal. I can’t figure out how to perform those same steps (press A, or Ctrl-C to cancel). Is it possible that the way to do this is to run a shell script that in turn runs osascript to run the shell script? (I actually found that a method like this works to get things done that I couldn’t figure out in other contexts, but can’t figure out how to accomplish this here.)
Also, of course, I suppose I could prompt the user to open a terminal and enter the command, but that only creates problems for the users I’m trying to support.
This gets the job done, but it would be nice to have a solution that doesn’t require the terminal:
on checkRosetta()
set ss to "processor=$(/usr/sbin/sysctl -n machdep.cpu.brand_string | grep -o \"Intel\")
if [[ -n \"$processor\" ]]; then
echo 'intel'
else
if [[ \"`pkgutil --files com.apple.pkg.RosettaUpdateAuto`\" == \"\" ]]
then
echo 'not-present'
else
echo 'installed'
fi
fi"
set rosetta to do shell script ss
if rosetta is "not-present" then
set doScript to "sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license"
display dialog "Rosetta 2 needs to be installed before I can run." & return & return & "When you click OK, I will open a terminal window." & return & return & "macOS will ask you to grant me permission to control the terminal. When you grant permission, I will enter the command that installs Rosetta 2." & return & return & "You will be prompted to enter an administrative password to install Rosetta 2, or you can press Ctrl-C to cancel." & return & return & "When Rosetta 2 is installed then run me again." buttons {"OK", "Cancel"} with title "Rosetta 2 required"
tell application "Terminal"
activate
do script doScript
end tell
error number -128
end if
end checkRosetta
My (very limited) understanding is that sudo should not be used in shell scripts in AppleScript, and with administrator privileges should be used instead (and definitely not both).
The command /usr/sbin/softwareupdate --install-rosetta --agree-to-license is supposed to agree to the license without requiring any user interaction. That’s the whole point of --agree-to-license in the first place.
Did you try:
do shell script "/usr/sbin/softwareupdate --install-rosetta --agree-to-license" with administrator privileges
Yes, of course you are right. Thank you. I haven’t actually completed the command because, when I do, Rosetta 2 will be installed on my test system, and I will have to erase the volume and reinstall the OS in order to test it again, but your suggestion is clearly right.