Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua

Home Page:http://www.hammerspoon.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot get hs.ipc.cli

z20240 opened this issue · comments

Cannot install hs cli tool

No matter how I type hs.ipc.cliInstall() or

ipc = require("hs.ipc")
ipc.cliInstall()

It always cannot install successfully.

image

what does hs.ipc.cliStatus() say?

As the figure, it only show false.

My Device is macOS Big Sur v11.5 with Apple M1.

I'm not sure if because of M1 to lead the cliInstall always return false.

commented

hs.ipc.cliInstall() requires write access to /usr/local/bin and /usr/local/share/man/man1 to install the command line client and man page. If you've installed Homebrew in its traditional location, this should be taken care of for you; if you're using an M1 Mac, and installed Homebrew in the recommended alternate location, then I think it's using /opt/homebrew instead... you could try hs.ipc.cliInstall("/opt/homebrew") which will leverage the already writable directories and path addition that Homebrew required.

If you're not using Homebrew at all, then you'll need to make the necessary directories writable by you in order to install the links to the command line tool... in a Terminal window, do the following (each line should be entered separately, and enter your password when prompted after the first command):

sudo chgrp admin /usr/local/bin
sudo chmod g+w /usr/local/bin
sudo mkdir -p /usr/local/share/man/man1
sudo chgrp admin /usr/local/share/man/man1
sudo chmod g+w /usr/local/share/man/man1

Now hs.ipc.cliInstall() should work without issue.

This should be added to the documentation, or maybe if hs.ipc.cliInstall() requires admin address to install we should request admin access if it doesn’t work the first attempt?

We could use something like this?

--- cp.tools.executeWithAdministratorPrivileges(input[, stopOnError]) -> boolean or string
--- Function
--- Executes a single or multiple shell commands with Administrator Privileges.
---
--- Parameters:
---  * input - either a string or a table of strings of commands you want to execute
---  * stopOnError - an optional variable that stops processing multiple commands when an individual commands returns an error
---
--- Returns:
---  * `true` if successful, `false` if cancelled and a string if there's an error.
function tools.executeWithAdministratorPrivileges(input, stopOnError)
    local originalFocusedWindow = window.focusedWindow()
    local whichBundleID = processInfo["bundleID"]
    local fcpBundleID = "com.apple.FinalCut"
    if originalFocusedWindow and originalFocusedWindow:application():bundleID() == fcpBundleID then
        whichBundleID = fcpBundleID
    end
    if type(stopOnError) ~= "boolean" then stopOnError = true end
    if type(input) == "table" then
        local appleScript = [[
            set stopOnError to ]] .. tostring(stopOnError) .. "\n\n" .. [[
            set errorMessage to ""
            set frontmostApplication to (path to frontmost application as text)
            tell application id "]] .. whichBundleID .. [["
                activate
                set shellScriptInputs to ]] .. inspect(input) .. "\n\n" .. [[
                try
                    repeat with theItem in shellScriptInputs
                        try
                            do shell script theItem with administrator privileges
                        on error errStr number errorNumber
                            if the errorNumber is equal to -128 then
                                -- Cancel is pressed:
                                return false
                            else
                                if the stopOnError is equal to true then
                                    tell application frontmostApplication to activate
                                    return errStr as text & "(" & errorNumber as text & ")\n\nWhen trying to execute:\n\n" & theItem
                                else
                                    set errorMessage to errorMessage & "Error: " & errStr as text & "(" & errorNumber as text & "), when trying to execute: " & theItem & ".\n\n"
                                end if
                            end if
                        end try
                    end repeat
                    if the errorMessage is equal to "" then
                        tell application frontmostApplication to activate
                        return true
                    else
                        tell application frontmostApplication to activate
                        return errorMessage
                    end
                end try
            end tell
        ]]
        local _,result = osascript.applescript(appleScript)
        if originalFocusedWindow and whichBundleID == processInfo["bundleID"] then
            originalFocusedWindow:focus()
        end
        return result
    elseif type(input) == "string" then
        local appleScript = [[
            set frontmostApplication to (path to frontmost application as text)
            tell application id "]] .. whichBundleID .. [["
                activate
                set shellScriptInput to "]] .. input .. [["
                try
                    do shell script shellScriptInput with administrator privileges
                    tell application frontmostApplication to activate
                    return true
                on error errStr number errorNumber
                    if the errorNumber is equal to -128 then
                        tell application frontmostApplication to activate
                        return false
                    else
                        tell application frontmostApplication to activate
                        return errStr as text & "(" & errorNumber as text & ")\n\nWhen trying to execute:\n\n" & theItem
                    end if
                end try
            end tell
        ]]
        local _,result = osascript.applescript(appleScript)
        if originalFocusedWindow and whichBundleID == processInfo["bundleID"] then
            originalFocusedWindow:focus()
        end
        return result
    else
        log.ef("ERROR: Expected a Table or String in tools.executeWithAdministratorPrivileges()")
        return nil
    end
end
commented

That actually looks like a potentially useful addition... I can't try it out right now, but if I'm following the logic correctly, you can send in a string or table of strings (like lines in a shell script?) and via applescript it will prompt for the admin password, correct?

Yes, correct. Just ignore all the FCPX specific stuff in that example.

Thanks a lot.

I tried hs.ipc.cliInstall("/opt/homebrew") can work.

I ll give it a try when I ll finish work! Thanks!

hs.ipc.cliInstall() requires write access to /usr/local/bin and /usr/local/share/man/man1 to install the command line client and man page. If you've installed Homebrew in its traditional location, this should be taken care of for you; if you're using an M1 Mac, and installed Homebrew in the recommended alternate location, then I think it's using /opt/homebrew instead... you could try hs.ipc.cliInstall("/opt/homebrew") which will leverage the already writable directories and path addition that Homebrew required.

If you're not using Homebrew at all, then you'll need to make the necessary directories writable by you in order to install the links to the command line tool... in a Terminal window, do the following (each line should be entered separately, and enter your password when prompted after the first command):

sudo chgrp admin /usr/local/bin
sudo chmod g+w /usr/local/bin
sudo mkdir -p /usr/local/share/man/man1
sudo chgrp admin /usr/local/share/man/man1
sudo chmod g+w /usr/local/share/man/man1

Now hs.ipc.cliInstall() should work without issue.

hs.ipc.cliInstall("/opt/homebrew") is what I need!