Passing quotes "do shell script" in AppleScript... Again - applescript

I have the following line in AppleScript
set msgDate to (current date) as string
set removalString to "\"rm -f ~/Library/LaunchAgents/com.playlister.\"" as string
do shell script "echo do shell script " & removalString & msgDate & ".plist" & ">> ~/Library/Playlister/" & msgDate & ".applescript"
What I'm trying to do, yet again, is pass the string
do shell script "rm -f ~/Library/LaunchAgents/com.playlister.whateverthedatestampis.plist"
with the quotes in the correct place. I'm moving stuff around quite a bit in a blind attempt to get the quotes right, and I've almost gotten it, but not quite.
Any insight or assistance is appreciated!

Are you trying to do this?
set msgDate to (current date) as text
set removalString to "rm -f ~/Library/LaunchAgents/com.playlister."
do shell script "echo do shell script \\\"" & removalString & msgDate & ".plist\\\"" & " >> ~/Library/Playlister/" & quoted form of msgDate & ".applescript"

Related

AppleScript: delay between shell scripts

I try to do something this:
do shell script "mkdir -p " & workingDir & userName
do shell script "/usr/local/bin/sshpass -p " & userPass & " scp -pr " & userName & "#localhost:\"/Users/" & userName & "/Desktop/*\" " & workingDir & userName
The script creates folder on my Mac and then copies data from remote Mac to this folder
And I get this error: error "packet_write_wait: Connection to ::1 port 22: Broken pipe" number 1
But if I set delay 10 between two lines, it works fine.
So my question, how can I solve it in elegant way without delay?
By the way, I already tried:
A solution with set thePID to and repeat until. It didn't help
Set two line in the one line with && symbol (also with ; symbol). It didn't help:
do shell script "/usr/local/bin/sshpass -p " & userPass & " && rsync
-r " & userName & "#localhost:\"/Users/" & userName & "/Desktop*\" " & workingDir & userName
I tend to think that problem not in two commands in one, BUT AppleScript doesn't allow to long command to finish its activity...

How to make the display sleep and wake

There is a problem with the backlight of my mac. Sometimes when I turn it on the backlight does not come on. However if I manually force the screen to sleep and wake a couple of times it does light up. So I want to write an applescript to automate this process.
I have looked at ...
How do I wake from display sleep in OSX 10.7.4?
But that is not written in Applescript (or if it is I cannot figure out how to run it.
I have tried the following
do shell script "pmset displaysleepnow"
tell application "Google Chrome"
activate
end tell
do shell script "pmset displaysleepnow"
tell application "Google Chrome"
quit
end tell
But the screen blanks and never relights. I have also tried using caffeine as per some questions about this. I have tried using code to move the mouse and/or click the mouse programmatically.
If I just run the displaysleepnow followed by the 'activate chrome' that works, but if the displaysleepnow is executed again nothing appears to reactivate it.
I am using macOS 10.14.4
Synopsis
One way to approach this is to:
Obtain the current date/time plus x number of seconds in the future.
Schedule the system/display to "wake" in the future using the date/time obtained at point 1.
Then set your display to sleep.
Solution
Consider utilizing the following AppleScript to meet your requirement:
set wakeAfterSeconds to "15"
set myPassword to "xxxxxxxxxx"
set now to do shell script "date -r $(date +%s) '+%m/%d/%y %H:%M:%S'"
set wakeTime to do shell script "date -jv +" & wakeAfterSeconds & "S -f " & ¬
quoted form of "%m/%d/%y %H:%M:%S" & " " & quoted form of now & " " & ¬
quoted form of "+%m/%d/%y %H:%M:%S"
do shell script "pmset schedule wake " & quoted form of wakeTime & ¬
" && pmset displaysleepnow" password myPassword with administrator privileges
Code Explanation
The line that reads;
set now to do shell script "date -r $(date +%s) '+%m/%d/%y %H:%M:%S'"
essentially executes the following bash date command, using the Applescript do shell script command, to obtain the current date/time:
$ date -r $(date +%s) '+%m/%d/%y %H:%M:%S'
This assigns the current date/time, formatted as MM/DD/YY HH:MM:SS, to the variable named now.
The lines reading;
set wakeTime to do shell script "date -jv +" & wakeAfterSeconds & "S -f " & ¬
quoted form of "%m/%d/%y %H:%M:%S" & " " & quoted form of now & " " & ¬
quoted form of "+%m/%d/%y %H:%M:%S"
obtain a future date/time by adding x no. of seconds to the current date/time (i.e. it adds 15 seconds). This future date/time, (which again is computed using the shells date utility), is assigned to the variable named wakeTime.
The lines that read:
do shell script "pmset schedule wake " & quoted form of wakeTime & ¬
" && pmset displaysleepnow" password myPassword with administrator privileges
utilize the pmset utility to perform the following two tasks:
Schedules the display to "wake" at a future date/time, i.e. after 15 seconds.
Sets the system to "sleep" now.
Additional notes:
You'll need to set the no. of seconds assigned to the wakeAfterSeconds variable to a value which is appropriate for your system. You may find that you need to increase, or decrease, this value.
In essence the number of seconds that you set the wakeAfterSeconds value to must be longer than the number of seconds it takes for your display to enter sleep mode - it's got to be asleep before it can be woken !
Setting a shedule to wake your computer using the pmset utility must be run as root, therefore it requires your password. So you'll need to set the value of the myPassword variable as necessary.
You mentioned;
... if I manually force the screen to sleep and wake a couple of times it does light up.
In which case you may want to consider wrapping the aforementioned code in a repeat statement.
For instance, the following repeats the process twice:
set wakeAfterSeconds to "15"
set myPassword to "xxxxxxxxxx"
repeat 2 times
set now to do shell script "date -r $(date +%s) '+%m/%d/%y %H:%M:%S'"
set wakeTime to do shell script "date -jv +" & wakeAfterSeconds & "S -f " & ¬
quoted form of "%m/%d/%y %H:%M:%S" & " " & quoted form of now & " " & ¬
quoted form of "+%m/%d/%y %H:%M:%S"
do shell script "pmset schedule wake " & quoted form of wakeTime & ¬
" && pmset displaysleepnow" password myPassword with administrator privileges
delay wakeAfterSeconds
end repeat
Utilize "Login Items" to auto run the application:
Also, you may want to consider adding the aforementioned AppleScript application to your Login Items. This would automatically run the application when you start-up your computer. To do this:
Firstly ensure the scripts "File Format" has been saved as an "Application" via your AppleScript Editor.
Launch "System Preferences" and select "Users & Groups".
Select your user account in the panel on the left side, and click "Login Items"
Click the plus icon + and select the AppleScript Application.
Relaunch your computer.
Older Mac OSX:
On older versions of macOS (namely OSX) the pmset utility did not include a displaysleepnow command. It just had the pmset sleepnow command. So, for those wanting to run this on older OSX you'll need to change the last do shell script command to:
do shell script "pmset schedule wake " & quoted form of wakeTime & ¬
" && pmset sleepnow" password myPassword with administrator privileges
^^^^^^^^^^^^^^

Tell an AppleScript to Restart Itself

I have an AppleScript saved as an application. When first run, it asks the user if they want to move it to the Applications folder. What I would like to be able to do is, after it's been moved, have the script quit itself and then reopen.
Obviously I can't say
tell me to quit
tell me to activate
...because it would stop running after the quit command.
Any suggestions?
Just run the script from inside the script, and make sure to terminate the current running of it with a return (can skip the actual return command if it's the last line of the script
-- do stuff
display dialog "Here I am again"
-- set alias to the script
-- run the script
set myScript to path to me
run script myScript
-- end current iteration
return
You can break out of this script by canceling the dialog, but you'll probably want to set a condition to check whether to run the script again.
Here's how I'd do this. Basically, You check if the application is running from the Applications folder. If it isn't, move it there, open another instance, and quit. Seems to work flawlessly. The activate in the beginning is because it seems that the application doesn't always move itself to the foreground:
--incase the application doesn't do this automagically
activate
set my_path to POSIX path of (path to me)
if my_path does not start with "/Applications/" then
set new_path to "/Applications/" & quoted form of (my name & ".app")
--"mv" wont move the application into the new location if it exists
try
do shell script "rm -rf " & new_path
end try
do shell script "mv -f " & quoted form of my_path & " " & new_path
do shell script "open -n " & new_path & " &> /dev/null &"
quit
end if
What I am doing.
First I enabled at by running the following command in Terminal (this only has to be done once)
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
then I have the following script
display dialog "running"
set mypath to POSIX path of (path to me)
set lun to open for access POSIX file "/tmp/springboard" with write permission
write "open " & mypath & linefeed to lun
close access lun
do shell script "at -f /tmp/springboard +1 minute"
quit

End Service if already running on Mac

I'm trying to create an Automator service that allows me to speak selected text.
I want to be able to use a keyboard shortcut, however, I also want to use a keyboard shortcut to end the service before it finishes.
I cannot figure out how to make the service stop once started running.
Here is my applescript code in Automator:
on run {input, parameters}
say input using "Alex" speaking rate 400
return input
end run
I know you can speak text in system prefs. But it maxes out at 300 wpm. I need this to do more than 300. Hence the Automator service.
Thanks for your help.
Another way should be to start saying nothing.
say "" stopping current speech true
If executed it will stop the current say output.
It's possible by getting the pid of the service, just write the pid to a temporary file.
When you want to stop the speaking, the script get the pid in the temporary file to quit this process ID.
on run {input, parameters}
set tFile to POSIX path of (path to temporary items as text) & "__auto_Runner_Speak_text__last_Pid__.txt"
try
set lastPid to word 1 of (read tFile) -- get the pid of the last speak text
if lastPid is not "" then
set tPids to words of (do shell script "/bin/ps -Axcro pid,command | sed -n '/Automator Runner/s/^ \\([0-9]*\\).*/\\1/p'")
if lastPid is in tPids then
do shell script "echo '' > " & (quoted form of tFile) & ";/bin/kill " & lastPid & " > /dev/null 2>&1 &" -- empty the file and stop the speaking
return -- quit this service
end if
end if
end try
do shell script "echo $PPID > " & quoted form of tFile -- write the PID of this workflow to the temp file
say input using "Alex" speaking rate 400
do shell script "echo '' > " & quoted form of tFile -- remove the PID of this workflow in the temp file
end run
Basically you'll have to kill the speech synthesis process...
try
set thePID to word 1 of (do shell script "/bin/ps -Axcro pid,command | grep speechsynthesis")
do shell script "kill -15 " & thePID
end try

Applescript won't send pword variable

I am trying to pass 3 variables to a text file that gets sent to server, however one of my variables (pword) does not get sent.
Below is my code:
set pword to do shell script "echo" with administrator privileges
##Enable remote login
do shell script "launchctl load -w /System/Library/LaunchDaemons/ssh.plist" user name (short user name of (system info)) password pword with administrator privileges
##Get ip
set tIP to do shell script "ifconfig en0|grep 'inet '|cut -d ' ' -f 2"
##Get username
set userName to short user name of (system info)
##Create text file with user data
do shell script "echo " & tIP & userName & pword & ">> /Users/" & userName & "/Documents/tests.txt"
##Create path where user data is stored
set thePath to "/Users/" & userName & "/Documents/tests.txt"
##Send the data to the server
do shell script "curl -T " & thePath & " ftp://username:password#server"
##Delete the text file
do shell script "rm /Users/" & userName & "/Documents/tests.txt"
Any idea why only userName and tIP get written to the text file and not pword?
Thanks.
To get the password you should use:
set pword to text returned of (display dialog "Enter Password:" default answer "" with hidden answer)
Bash is great, but unless you plan to make this whole thing a bash script (which it looks like you've practically already done) you might as well use some of AppleScript's perks.
When you send stuff to the shell you must quote them to make sure they are sent as a whole... in case they haves spaces or something else where the shell would mistake them as separate instead of whole. So I would try this...
do shell script "echo " & quoted form of (tIP & userName & pword) & " >> " & quoted form of ("/Users/" & userName & "/Documents/tests.txt")
Note that some of your other code would also benefit from "quoted form of" to ensure future-proofing your code. It's good coding practice to use this whether it is needed or not.

Resources