I'm trying to make an AppleScript where you change your Mac's local hostname. I'm trying to do it through a terminal command, but if the user wants spaces in the hostname, It doesn't work, as for the command with spaces to work, you need inverted commas, and as far as I'm aware of, you can't do add " as text in AppleScript. Here's what i'm trying to do:
set computername to display dialog "Type the desired name" default answer "" with icon note buttons {"Continue"} default button "Continue" as text
display dialog (text returned of computername) & " is this correct? " & "."
display dialog "If it askes you, please type your password in. (It may ask more than once)"
do shell script "scutil --set LocalHostName " & """ & (text returned of computername) & """
display dialog "Changes will be applied after a restart. Click continue to save changes and restart."
do shell script "shutdown -r now"
I need to enter " before the name is entered, as well as after.
do shell script "scutil --set LocalHostName " & """ & (text returned of computername) & """
but I just get errors
Thanks in advance
First of all you're encouraged to convince the user not to use space characters in the host name. It's very error-prone to do so.
AppleScript provides a simple solution to handle escaping parameters in shell scripts properly:
do shell script "scutil --set LocalHostName " & quoted form of (text returned of computername)
Related
I'm trying to create a script that asks the user what .mp3 they want to split using Terminal through AppleScript / Script Editor. Here's what I have so far.
I am trying to get input to display in this line:
do script "spleeter separate -i (text returned of input).mp3 -p spleeter:2stems -o output"
in terminal, it just says that there are no matches found for (text returned of input).
Here's my code:
set input to display dialog "What would you like to convert?" default answer "" with icon note buttons {"Continue", "Cancel"} default button "Continue"
tell application "Terminal"
do script "cd Desktop/spleetr"
do script "spleeter separate -i (text returned of input).mp3 -p spleeter:2stems -o output"
end tell
You are placing a command inside a string, so it is not getting evaluated. The solution for that is to concatenate the results of the command and the string parts in the desired order.
When using the Terminal, unless specified otherwise, each do script command is run in its own window/tab. If you don't neccessarily need a Terminal window, the do shell script command can be used instead (note that it uses a default shell, so you should use full paths), but to use multiple commands with either one you need to combine the various shell commands into a single statement, otherwise they will be run in separate shells.
I don't have that utility to test, but in the following script I am getting the text in the dialog statement, and quoting the result for the shell script in case it contains spaces, etc:
set input to text returned of (display dialog "What would you like to convert?" default answer "" with icon note buttons {"Continue", "Cancel"} default button "Continue")
-- to run in a new Terminal window: --
tell application "Terminal"
do script "cd Desktop/spleetr; spleeter separate -i " & quoted form of (input & ".mp3") & " -p spleeter:2stems -o output"
end tell
-- or if Terminal is not needed: --
do shell script "cd Desktop/spleetr; spleeter separate -i " & quoted form of (input & ".mp3") & " -p spleeter:2stems -o output"
There is an article (https://medium.com/#mrdoro/fast-translation-with-google-translator-and-mac-osx-817e32233b7a) from Lukasz Dorosz
about using Apple Automator to integrate Google translator with macOS. I did it and it works. My question is - How can I integrate DeepL translator with macOS?
Using Automator you can integrate a Goole Translator with macOS in few steps:
Open an Automator and create a new Service.
The top section set in this way:
From the left column you need to find and grab two functions: Run >Apple Script and Website Popup.
Copy and Paste this code into Apple Script window.
on run {input, parameters}
set output to "http://translate.google.com/translate_t?sl=auto&tl=ru&text=" & urldecode(input as string)
return output
end run
on urldecode(x)
set cmd to "'require \"cgi\"; puts CGI.escape(STDIN.read.chomp)'"
do shell script "echo " & quoted form of x & " | ruby -e " & cmd
end urldecode
How do I change the script to use the translator from DeepL instead of Google?
You can see the DeepL link format by clicking the share button. The links look like this:
https://www.deepl.com/translator#de/en/Dies%20ist%20kein%20Haus.
So your script should look something like this:
on run {input, parameters}
set output to "https://www.deepl.com/translator#de/en/" & urldecode(input as string)
return output
end run
on urldecode(x)
set cmd to "'require \"cgi\"; puts CGI.escape(STDIN.read.chomp)'"
do shell script "echo " & quoted form of x & " | ruby -e " & cmd
end urldecode
If the text is long enough, the source language in the link should also be irrelevant, since the DeepL language recognizer determines the actual language.
The DeepL app that #tecmec recommended in his comment is probably much better than any script.
I have several hundred lengthy applescripts to edit where I need to find and replace the following code snippet in various places in each script.
tell application "Adobe Photoshop CC 2015.5"
set myLayer to current layer of current document
if last character of mySport is "s" then
set contents of text object of myLayer to mySport & ""
else
set contents of text object of myLayer to mySport & "'s"
end if
end tell
I want to replace it with
tell application "Adobe Photoshop CC 2015.5"
set myLayer to current layer of current document
set contents of text object of myLayer to mySport & "'s"
end tell
Is there a way to write an applescript to find and replace several lines?
code screen grab
The second problem is how do I deal with the apostrophe contained inside the quotes?
You can probably tell that I'm an artist and not a developer or scripter! I tried to get an answer a while back but unsuccessfully and the problem is now become critical.
Many thanks in anticipation of an answer.
The best would have been to set this subroutine as a separate script library and call it it in each of your scripts. Doing so, only one change would be enough. I advice you to do this way for next time.
I dig to find a way to make change in a script, but that's not that easy. Script Editor as very limited capability for scripting. the work around is to use the GUI scripting, which means that any changes made by Apple in future versions may no longer work.
The script bellow simulate your keyboard action to search & replace CurString to NewString :
set myScript to "Users:imac27:Desktop:Testscript.scpt" -- path to your script
set CurString to "Set B to 2"
set NewString to "Set X to 5"
tell application "Script Editor"
open myScript
activate myScript
delay 2
tell application "System Events"
keystroke "f" using {option down, command down} --mode search & replace
keystroke tab using {shift down} -- got to search area
keystroke CurString -- set the search target
keystroke tab -- goto replace area
keystroke NewString -- set replace value
-- click on menu "Replace all " which is the 7th item of "Search" menu item (=item 14th of menu "Edit")
tell process "Script Editor" to click menu item 7 of menu of menu item 14 of menu 4 of menu bar 1
end tell
compile front document
save front document
close front document
end tell
This script opens the script, it does the search, replaces, clicks on "replace" menu, then it compiles new version, saves it and closes it. If you have many scripts, you must run it through a loop for each script.
I tested it OK with simple line : replace "Set B to 2" by new line "Set X to 5".
However, your issue is more complex because you want to replace several lines, not only 1. I did not found a way to set the search area with multiple lines. I tried with CR (13) or LF (10), but it does not work. May be someone has an idea for that part ?
Also, if you want to add a " in your search or replace patterns, you can use the following :
set Guil to ASCII character 34
Set CurString to "this is a " & Guil & "s" & Guil & " between quotes"
In this case, the CurString value will be : this is a "s" between quotes
I purchased Script Debugger from Late Night Software and it enables the script to access pieces of code and replace them. Mark Alldritt was amazing in the support he offered and the software is now my "first use" destination.
You are sure of your original script and the final script? In this case no hesitation to use xxd and sed below in hexadecimal script which you wrote you can test this script, no danger for your script. Naturally, you change your path and names at your convenience.
set thePath to POSIX path of (choose file)
tell application "Script Editor"
set doc to open thePath
save doc as "text" in POSIX file "/Users/yourname/Desktop/yourscriptold.txt"
close thePath
end tell
set scp to do shell script "xxd -p -c 100000 /Users/yourname/Desktop/yourscriptold.txt " & " | sed -e 's#74656c6c206170706c69636174696f6e202241646f62652050686f746f73686f7020434320323031352e35220a736574206d794c6179657220746f2063757272656e74206c61796572206f662063757272656e7420646f63756d656e740a6966206c61737420636861726163746572206f66206d7953706f727420697320227322207468656e0a73657420636f6e74656e7473206f662074657874206f626a656374206f66206d794c6179657220746f206d7953706f727420262022220a656c73650a73657420636f6e74656e7473206f662074657874206f626a656374206f66206d794c6179657220746f206d7953706f7274202620222773220a656e642069660a656e642074656c6c#74656c6c206170706c69636174696f6e202241646f62652050686f746f73686f7020434320323031352e35220a736574206d794c6179657220746f2063757272656e74206c61796572206f662063757272656e7420646f63756d656e740a73657420636f6e74656e7473206f662074657874206f626a656374206f66206d794c6179657220746f206d7953706f7274202620222773220a656e642074656c6c#' > /Users/yourname/Desktop/yourscriptnew.txt"
set scp to do shell script "xxd -r -p /Users/yourname/Desktop/yourscriptnew.txt >/Users/yourname/Desktop/yournewscript.txt"
do shell script "osacompile -o " & "/Users/yourname/Desktop/temporyname.scpt" & " /Users/yourname/Desktop/yournewscript.txt"
do shell script "rm -f /Users/yourname/Desktop/yourscriptold.txt "
do shell script "rm -f /Users/yourname/Desktop/yourscriptnew.txt "
do shell script "rm -f /Users/yourname/Desktop/yournewscript.txt "
So, I am trying to create an app with AppleScript, but when I move my app in a different folder and run it, it always will look at the folder it was in before.
display dialog "Kindle Fire HDX 7" Utility Mac
Please select the action you want to do.
Make sure a Terminal window is OPENED!!!"
buttons {"Connected Devices", "Reboot", "More..."} default button 3
set the button_pressed to the button returned of the result
if the button_pressed is "Connected Devices" then
-- action for 1st button goes here
tell application "Terminal"
VVVV Right here is error
if (count of windows) is not 0 then
do script "cd ~/Desktop/ADB-GUI/Kindle Fire HDX 7" Utility.app/Contents/Resources/minerboyadb/ && ./adb devices"
^^^^ Right here is error
end if
else if the button_pressed is "" then
-- action for 2nd button goes here
else
-- action for 3rd button goes here
end if
Is there a way to fix this? Or is it possible to use Xcode to make an AppleScript app? (Which might work better.)
Your code, as posted as of this writing, won't compile, but to answer the question in general:
POSIX path of (path to me)
will return the POSIX path to the running AppleScript-based application from within it, including a trailing /; e.g.: "/Applications/MyAppleScriptApp.app/"
Aside from that, you should always use quoted form of when adding an argument to a shell-command string for use with do script or do shell script, so as to ensure that it is preserved as-is and doesn't break the overall shell command.
Furthermore, assuming your intent is to simply display/capture the output from a shell command, use do shell script, which runs a shell command hidden and returns its stdout output; e.g.:
set cmdOutput to do shell script "ls"
display alert "Files in current folder" message cmdOutput
So I have this Applescript:
on run{}
set myPath to path to me as text
set x to the length of myPath
set myPath to characters 13 thru x of myPath as string --Removes "Macintosh HD:" from the front of the file path
set myPath to my fileAdapt(myPath)
set lat to do shell script myPath & " -f \"{LAT}\"" --See comments below the script
set lon to do shell script myPath & " -f \"{LON}\""
end run
on fileAdapt(myPath)
set x to the length of myPath
set myPath1 to ""
repeat with i from 1 to x
if character i of myPath is ":" then
set myPath1 to myPath1 & "/"
else if character i of myPath is " " then
set myPath1 to myPath1 & "\\ "
else
set myPath1 to myPath1 & (character i of myPath)
end if
end repeat
set myPath1 to myPath1 & "Contents/Resources/LocateMe" as string --See comments below the script
return myPath1
end fileAdapt
where LocateMe is a bash script that can get a user's latitude and longitude, among other statistics, using the -f command.
The Issue
Now, on first run, the program asks for permission to get the user's location. If the user presses "OK," then all is good. But if the user presses "Cancel," we've got issues.
As I describe over on SuperUser regarding deleting applications from Location Services, LocateMe seems to continue running in the background until Location Services are turned back on. In the meantime, my Applescript just hangs until the bash script finishes loading, or until I force-quit the application (or Script Editor, whatever I'm running it in). Obviously, this is not a desirable behavior.
To make matters worse, once the application has asked for Location Services permission, it never asks again; the user has to manually go to System Preferences and tick the box themselves (or get a script to do it for him). What this means is that on a second run of this script, the user would have absolutely no way of knowing why the script is hanging.
My first attempt at dealing with this was to stuff LocateMe inside a try statement, but, as per my conclusion above, that wouldn't do anything; since LocateMe continues running until it gets access to the user's location, the Applescript never reaches the on error line.
My Question
I would like to know if there is a way to call LocateMe from within some sort of statement, be it an Applescript or a bash script or some other language that can be run from within an Applescript, that sets a time limit; if the time limit is not reached, LocateMe will be terminated, and the Applescript will display an error message to the user, explaining that location services must be turned on.
This is a possible duplicate of How to introduce timeout for shell scripting?
If you have timeout available, simply run timeout -k 10 Contents/Resources/LocateMe (where 10 is the number of seconds before timeout.
Otherwise either call that expect command directly, replacing $command with Contents/Resources/LocateMe, or copy that function into your .bashrc so that the function timeout is available in bash, and call that.
That expect example is defining a bash function - when you call functions with arguments, they get put into variables called $1, $2 etc. So for timeout 10 foo, $1 would be 10 and $2 would be foo. If you copy it 'as-is' into your .bashrc you can use it in the same way as the timeout command suggested above. Alternatively, just copy the expect line out of the function into your script, and replace all the variables with hard-coded values (time, command etc).