Can't make Unix ID of Process into text? - shell

I have a modbook with a glitchy digitizer board. Until I can re-shield the cable that is causing the glitch I just want to turn the digitizer off. I found a page which taught me some code and I used it successfully last night. Upon reboot, however, it doesn't work anymore:
The script:
tell application "System Events"
set PTD to (unix id of process "PenTabletDriver") as text
do shell script "kill -STOP " & quoted form of (PTD)
end tell
The error message:
error "Can’t make «class idux» of «class prcs» \"PenTabletDriver\" of
application \"System Events\" into type text." number -1700 from
«class idux» of «class prcs» "PenTabletDriver" to text
Can I alter the code somehow to fix this problem?
PS:
I have read this post and, though it's similar, I do not understand how it could be applied to my problem.

Life is too short to mess with AppleScript. Try running the following command at the terminal prompt:
pkill -STOP PenTabletDriver
Also, check your login items to see if the driver is automatically started each time you log in. (More likely, though, is that it's configured to start at boot time via launchd.)

You can save the following script in a little applet:
set shellStr to "pkill -STOP PenTabletDriver"
do shell script shellStr
and run it whenever you need.

I think the other answers make a good point, a shell command is nice and quick. BUT, if you must have it in AppleScript, this seems to work for me....
tell application "System Events"
set PTD to (unix id of process "iTunes")
do shell script "kill -STOP " & quoted form of (PTD as text)
end tell
which results to
tell application "System Events"
get unix id of process "iTunes"
--> 37987
do shell script "kill -STOP '37987'"
--> error number -10004
end tell
tell current application
do shell script "kill -STOP '37987'"
--> ""
end tell
The Process ID is just a number so there is no need to quote it...
tell application "System Events"
set PTD to (unix id of process "iTunes")
do shell script "kill -STOP " & PTD
end tell
The above code is sufficient.

Related

Killing all Adobe Background processes when not needed MAC

This code and question is following on from perfectfiasco question and answer by Ted Wrigley.
I too find it crazy how many processes Adobe runs in the background - even when finder extensions are disabled and not using any apps.
I am trying to create something similar but for 3 additional apps also Lightroom / creative cloud and adobe bridge also and have edited it slightly to include all the other processes that Adobe run in the background. Any idea if I have added these correctly?
Not entirely sure how to separate apps from processes and if its necessary to killall for apps or just quit command?
Is it fine to force quit process and apps like this?
Something I have noticed is that if lots of adobe processes are quit then it launches this daemon "AdobeCRDaemon" is that expected?
Not sure what to put here now several other processes have been added - tell process "AGMService"
Does anything else in the code need updating for current macOS Monterey ?
Thank you in advance for any clarification
use AppleScript version "2.4"
use framework "AppKit"
use scripting additions
property NSWorkspace : class "NSWorkspace"
on run
set workSp to NSWorkspace's sharedWorkspace()
set notifCent to workSp's notificationCenter()
tell notifCent to addObserver:me selector:"someAppHasTerminated:" |name|:"NSWorkspaceDidTerminateApplicationNotification" object:(missing value)
end run
on idle
-- we don't use the idle loop, so tell the system let the app sleep. this comes out of idle once an hour
return 3600
end idle
on someAppHasTerminated:notif
set termedApp to (notif's userInfo's valueForKey:"NSWorkspaceApplicationKey")
set termedAppName to (termedApp's localizedName) as text
-- I'm guessing at the localized names for Photoshop and Illustrator. you may need to alter these
if termedAppName is "Adobe Photoshop 2022" or termedAppName is "Adobe Lightroom Classic" or termedAppName is "Adobe Bridge 2022" or termedAppName is "Adobe Lightroom" or termedAppName is "Creative Cloud" then
-- close the service here
tell application "System Events"
tell process "AGMService"
if its accepts high level events is true then
tell application "AGMService" to quit
tell application "Adobe Desktop Service" to quit
tell application "CCLibrary" to quit
tell application "CCXProcess" to quit
tell application "Core Sync" to quit
tell application "Creative Cloud Helper" to quit
else
do shell script "killall AGMService"
do shell script "killall Adobe Desktop Service"
do shell script "killall CCLibrary"
do shell script "killall CCXProcess"
do shell script "killall Core Sync"
do shell script "killall Creative Cloud Helper"
end if
end tell
end tell
end if
end someAppHasTerminated:
This is a deeply unsafe way to do this, but I've replaced the nested tell hell in onAppHasTerminated this:
do shell script "pkill -i -f adobe"
My personal script looks like this.
I had the same problem.
Just run this command in terminal:
kill $(ps aux | grep -i '.adobe' | grep -v grep | awk '{print $2}')

AppleScript - wait for do shell script done

I write a Command Line Tool to fetch movie information from IMDB. It's in JavaScript and called movinfo. I run it in AppleScript:
tell application "System Events"
set movT to "Back-to-the-future"
set exportPath to "export PATH=$PATH:/usr/local/bin:;"
set oriInfo to do shell script exportPath & "movinfo " & quoted form of movT
return oriInfo
end tell
It works great. But sometimes movinfo takes long time to fetch the information from the Internet. So I want to add a function to check if the fetching is done or not. I try "ignoring...end ignoring" structure firstly:
tell application "System Events"
ignoring application responses
set movT to "Back-to-the-future"
set exportPath to "export PATH=$PATH:/usr/local/bin:;"
set oriInfo to do shell script exportPath & "movinfo " & quoted form of movT
end ignoring
end tell
tell application "System Events"
repeat 30 times
try
return oriInfo
exit repeat
on error
delay 1
end try
end repeat
do shell script "killall System\\ Events"
end tell
But this doesn't work. Maybe I can do something with the Command Line Tool to do this job. But I really don't know too much about JavaScript, and CLI. I want to do this in AppleScript.
Hope someone can tell me what's wrong with the code, or how to do this in AS?
Note that I don't have the movinfo utility (you neglected to provide a link) so I can't test this, but it should work on face value.
First (as vadian pointed out in comments) you don't need the System Events tell blocks as you've used them, so I've restructured that. The trick here is to detach the movinfo utility so it runs as a process independent of the script, writing the movie info into a file at ~/movieInfo.txt. The script then recovers the process pid from the do shell script, and waits for the utility to end, using system events to test if a process with that pid is still running. When the process ends,
the script reads the info from the file back into the oriInfo variable. For questions about the unix tricks, see: Technote 2065.
-- set output file path
set movieInfoFile to POSIX path of (path to home folder from user domain) & "movieInfo.txt"
set movT to "Back-to-the-future"
set exportPath to "export PATH=$PATH:/usr/local/bin:;"
-- run and detach utility, returning its process id
set procID to do shell script exportPath & "movinfo " & quoted form of movT & " &> " & movieInfoFile & " & echo $!"
repeat 30 times
tell application "System Events"
-- test if pid is still active
set isStillRunning to count of (every process whose unix id is procID)
end tell
if isStillRunning = 0 then
--not active, so proceed
exit repeat
else
delay 1
end if
end repeat
-- pull info from file
set fp to open for access movieInfoFile
set oriInfo to read fp
close access fp

Running multiple Applescripts in order in Automator

I am trying to automate this process.
step 1: change system date to a specific date.
step 2: open an application.
step 3: change system date back to normal.
Now on Automator, I have three apple scripts placed like this.
on run {input, parameters}
tell application "Terminal"
do script with command "sudo date 082704002018"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "open -a applicationName"
activate
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "sudo ntpdate -u time.apple.com"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
The problem is that Automator only runs the first code. I'm not sure how to make it run all the codes in order.
Sorry if this is a stupid question. I am completely new to automator and applescript.
Thank you
I'm not quite sure why you chose to use three separate AppleScripts. You can combine them all into one AppleScript as I have done in this following example. I'm not quite sure why you used the “activate” commands. I don't think they are necessary so I removed those lines of the code. Anyway, this following code should work for you…
tell application "Terminal"
do script with command "sudo date 082704002018"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
tell application "Terminal"
do script with command "open -a applicationName"
delay 1
do script with command "sudo ntpdate -u time.apple.com"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
Alternately, launching Terminal app to run shell scripts is not necessary all the time as you can run shell scripts in AppleScript by using the “do shell script” command. This following applescript code is your code using only eight lines of code.
do shell script "sudo date 082704002018"
tell application "System Events" to keystroke "mypassword" & return
delay 3
do shell script "open -a applicationName"
delay 1
do shell script "sudo ntpdate -u time.apple.com"
delay 1
tell application "System Events" to keystroke "mypassword" & return
If my versions of your code throw errors, it may be necessary to adjust the delay commands or re-insert the activate commands
If you are hell-bent on using your version of the code and three separate Applescripts, just remove the on run {input, parameters} and end run lines of code from each AppleScript and that should eliminate your problem

Use Applescript to Enter command into Terminal but do not Execute

Using Applescript, is it possible to open a new Terminal and enter the command into the terminal but do not run it?
tell application "Terminal"
do script "echo Hello"
end tell
This code will type the line echo Hello into the Terminal and run it. Can we avoid the execution?
Good case for System Events app and emulating keystrokes:
tell application "Terminal" to activate -- only needed if Terminal may not be running
tell application "System Events"
tell application process "Terminal"
set frontmost to true
keystroke "echo Hello"
end tell
end tell

Sending commands and strings to Terminal.app with Applescript

I want to do something like this:
tell application "Terminal"
activate
do script "ssh user#server.com"
-- // write user's password
-- // write some linux commands to remote server
end tell
For example to log in to the server, enter the password, and then login to mysql and select a DB.
I type that every day and it would be really helpful to bundle it into a script.
Also, is there a reference of what commands, properties, functions, etc. do applications (Terminal, Finder, etc) have available to use within Applescript? thanks!
EDIT: Let me clear this up:
I don't want to do several 'do script' as I tried and doesn't work.
I want to open a Terminal window, and then emulate a human typing in some characters and hitting enter. Could be passwords, could be commands, whatever, just sending chars to the Terminal which happens to be running ssh. I tried keystroke and doesn't seem to work.
First connect to the server and wait for 6 seconds (you can change that) and then execute whatever you need on the remote server using the same tab
tell application "Terminal"
set currentTab to do script ("ssh user#server;")
delay 6
do script ("do something remote") in currentTab
end tell
As EvanK stated each do script line will open a new window however you can run two commands with the same do script by separating them with a semicolon. For example:
tell application "Terminal"
do script "date;time"
end tell
But the limit appears to be two commands.
However, you can append "in window 1" to the do script command (for every do script after the first one) to get the same effect and continue to run as many commands as you need to in the same window:
tell application "Terminal"
do script "date"
do script "time" in window 1
do script "who" in window 1
end tell
Note that I just used the who, date, and time command as an example...replace
with whatever commands you need.
Here's another way, but with the advantage that it launches Terminal, brings it to the front, and creates only one window.
I like this when I want to be neatly presented with the results of my script.
tell application "Terminal"
activate
set shell to do script "echo 1" in window 1
do script "echo 2" in shell
do script "echo 3" in shell
end tell
How about this? There's no need for key codes (at least in Lion, not sure about earlier), and a subroutine simplifies the main script.
The below script will ssh to localhost as user "me", enter password "myPassw0rd" after a 1 second delay, issue ls, delay 2 seconds, and then exit.
tell application "Terminal"
activate
my execCmd("ssh me#localhost", 1)
my execCmd("myPassw0rd", 0)
my execCmd("ls", 2)
my execCmd("exit", 0)
end tell
on execCmd(cmd, pause)
tell application "System Events"
tell application process "Terminal"
set frontmost to true
keystroke cmd
keystroke return
end tell
end tell
delay pause
end execCmd
You don't need to "tell" Terminal to do anything. AppleScript can do shell scripts directly.
set theDir to "~/Desktop/"
do shell script "touch " & theDir &"SomeFile.txt"
or whatever ...
Why don't use expect:
tell application "Terminal"
activate
set currentTab to do script ("expect -c 'spawn ssh user#IP; expect \"*?assword:*\"; send \"MySecretPass
\"; interact'")
end tell
Your question is specifically about how to get Applescript to do what
you want. But, for the particular example described, you might want
to look into 'expect' as a solution.
Kinda related, you might want to look at Shuttle (http://fitztrev.github.io/shuttle/), it's a SSH shortcut menu for OSX.
The last example get errors under 10.6.8 (Build 10K549) caused by the keyword "pause".
Replacing it by the word "wait" makes it work:
tell application "Terminal"
activate
my execCmd("ssh me#localhost", 1)
my execCmd("myPassw0rd", 0)
my execCmd("ls", 2)
my execCmd("exit", 0)
end tell
on execCmd(cmd, wait)
tell application "System Events"
tell application process "Terminal"
set frontmost to true
keystroke cmd
keystroke return
end tell
end tell
delay wait
end execCmd
I could be mistaken, but I think Applescript Terminal integration is a one-shot deal...That is, each do script call is like opening a different terminal window, so I don't think you can interact with it at all.
You could copy over the SSH public keys to prevent the password prompt, then execute all the commands joined together (warning: the following is totally untested):
tell application "Terminal"
activate
do script "ssh jdoe#example.com '/home/jdoe/dosomestuff.sh && /home/jdoe/dosomemorestuff.sh'"
end tell
Alternatively, you could wrap the ssh and subsequent commands in a shell script using Expect, and then call said shell script from your Applescript.
set up passwordless ssh (ssh-keygen, then add the key to ~/.ssh/authorized_keys on the server). Make an entry in ~/.ssh/config (on your desktop), so that when you run ssh mysqlserver, it goes to user#hostname... Or make a shell alias, like gotosql, that expands to ssh user#host -t 'mysql_client ...' to start the mysql client interactively on the server.
Then you probably do need someone else's answer to script the process after that, since I don't know how to set startup commands for mysql.
At least that keeps your ssh password out of the script!
Petruza,
Instead of using keystroke use key code.
The following example should work for you.
tell application "System Events"
tell application process "Terminal"
set frontmost to true
key code {2, 0, 17, 14}
keystroke return
end tell
end tell
The above example will send the characters {d a t e}
to Terminal and then keystroke return will enter and run
the command. Use the above example with whatever key codes you need
and you'll be able to do what you're trying to do.
what about something like this:
tell application "Terminal"
activate
do shell script "sudo dscl localhost -create /Local/Default/Hosts/cc.josmoe.com IPAddress 127.0.0.1"
do shell script "sudo dscl localhost -create /Local/Default/Hosts/cc.josmos2.com IPAddress 127.0.0.1"
end tell
As neat solution, try-
$ open -a /Applications/Utilities/Terminal.app *.py
or
$ open -b com.apple.terminal *.py
For the shell launched, you can go to Preferences > Shell > set it to exit if no error.
That's it.
I built this script. It is in Yosemite and it is bash script using AppleScript to choose a list of users for SSH servers. Basically you define an IP and then the user names.. when the application launches it asks who you want to login in as.. the SSH terminal is launched and logged in prompting a password...
(***
* --- --- --- --- ---
* JD Sports Fashion plc
* Apple Script
* Khaleel Mughal
* --- --- --- --- ---
* #SHELLSTAGINGSSHBASH
* --- --- --- --- ---
***)
set stagingIP to "192.162.999.999"
set faciaName to (choose from list {"admin", "marketing", "photography_cdn"})
if faciaName is false then
display dialog "No facia was selected." with icon stop buttons {"Exit"} default button {"Exit"}
else
set faciaName to (item 1 of faciaName)
tell application "Terminal"
activate
do script "ssh " & faciaName & "#" & stagingIP & ""
end tell
end if
I highly recommend though; Nathan Pickmans post above about Shuttle (http://fitztrev.github.io/shuttle/).. a very smart and simple application.

Resources