How to rename files as they are added to a folder? - macos

I created an Automator workflow that renames iOS Simulator Screenshots as they are added to the Desktop folder. But for the workflow to work, I need to run it myself manually. Is there a way to make the workflow watches the Desktop folder continuously and renames screenshots as they are added like a background service?
This is the workflow I created :
Screenshot of the Workflow

I find automator to be a a bit clunky at times, so I suggest you do this with a standard AppleScript Folder Action. Copy the following script into Script Editor.app, modify the prefixes as needed, then save it in ~/Library/Scripts/Folder Action Scripts.
property old_prefix : "Simulator Screen Shot - "
property new_prefix : "some text "
on adding folder items to this_folder after receiving these_items
repeat with this_item in these_items
set item_path to POSIX path of this_item
tell application "System Events"
set this_disk_item to disk item item_path
tell this_disk_item
if its name begins with old_prefix then
set its_extention to its name extension
set its_name to its displayed name
set new_file_name to new_prefix & (text ((length of old_prefix) + 1) through -1 of its_name)
if new_file_name ≠ its displayed name and new_file_name ≠ "" then
set name of this_disk_item to new_file_name & "." & its_extention
end if
end if
end tell
end tell
end repeat
end adding folder items to
Use Spotlight to open the app "Folder Actions Setup", add your desktop as a folder on the left side, and on the right, select and attach the script you just saved to that folder. It should 'just work'.

The way I would do it is to use an application called launchd to open the automator script how ever often you need (e.g. every few seconds). This website describes how to set it up. Basically you have to first save your automator script as an application into a certain folder (e.g. Documents), then write a short xml script which tells launchd which file to open and how often to do it.
Below is a sample script:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.NAME.test</string>
<key>Program</key>
<string>/Users/USERNAME/Documents/test.app/Contents/MacOS/Application Stub</string>
<key>StartInterval</key>
<integer>5</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Open a new "Plain text" TextEdit document and paste in the above. Replace the Label (com.NAME.test) with whatever you want; I usually just put my name in there, followed by the name of the script. Next change the line under Program to the location of your ".app" file you saved earlier, remembering to change USERNAME to your username. Keep in mind that the /Contents/MacOS/Application Stub needs to be right after the ".app" part so that the script will start your application. Then change the line under StartInterval to the number of seconds you want the script to wait before it runs again.
After you're done editing the script, save it to "/Users/USERNAME/Library/LaunchAgents/com.NAME.test.plist," of course changing USERNAME to your username and com.NAME.test to the Label used in the xml script. If it asks if you want to save it with the ".plist" extension, choose yes. Once the file's saved, open up Terminal (/Applications/Utilities/Terminal.app) and type in the command launchctl load /Users/USERNAME/Library/LaunchAgents/com.NAME.test.plist, changing the file name to the filepath of your ".plist" file. Use unload instead of load to stop the script from running.
For me a gear icon kept appearing in the menu bar every time the script ran, so I found on this and this website that you can stop it by adding "Run Shell Script" to the very top of your Automator script, then typing in the box killall ScriptMonitor || true.

Related

MacOS Terminal: Is it possible to create a "drag-and-drop" action via script?

There are many posts that explain how to drag-and-drop things into an open Terminal window. But what I would like to do is to tell Terminal to drag-and-drop a previously selected directory onto another application like VSCode or Renamer. I have not found any documentation for that. Is it at all possible? And if so, would somebody please point me to a documentation?
UPDATE:
I'd like to clarify my question with what I intend to do:
Pre requisites:
a "work folder" contains folders and files that shall be renamed
the renaming is done by an application called "A better finder renamer" (which allows presets)
An "Automator" (MacOS app) action shall imitate these steps:
the "work folder" is right clicked
the folder is drag-and-dropped onto the ABFR, which initiates the currently active preset
other actions via bash (like 'mv .//.* ./') ...
It is the "drag-and-drop" part of the Automator action that presents a riddle for me.
The "drag-and-drop" operation is manual operation. In AppleScript, instead the command to open the file or folder is given to the destination application itself.
Second thing to keep in mind. Getting Terminal's current working directory is easy with its do script "pwd" command. But the result of the do script Terminal command returned to the script is always the window tab, not the result of the pwd shell command. One solution is to redirect (remember) the result of pwd in a temporary text file.
set tempFolder to (path to temporary items folder from user domain)
set temp to POSIX path of tempFolder & "workingDirectory.txt"
tell application "Terminal" to do script ("pwd > " & temp) in selected tab of window 1
set curDirPosixPath to paragraph 1 of (read file ((tempFolder as text) & "workingDirectory.txt"))
set curDirHFSPath to curDirPosixPath as POSIX file as Unicode text
tell application "Visual Studio Code" to open curDirHFSPath
.
NOTE: other possible solution (I don't like) is parsing the text contents of Terminal window after pwd command execution. You can get contents using property contents (of selected tab of front window).
Open Automator, choose create New Document.
Choose create new Quick Action (service).
Set workflow receives current folders in any application.
From library Add Run AppleScript action. Edit it contents:
on run {input, parameters}
set curDirHFSPath to (item 1 of input) as text
tell application "Visual Studio Code" to open curDirHFSPath
end run
Save this Quick Action as service. Now when right-clicking the folder, opens the context menu, where you can choose and run this service.

Run a Terminal command on open location AppleScript

I want to run a command in terminal when a custom url is called.
Example :
I want to open a terminal and run echo "hello myapp://hello" when someone opens myapp://hello in browser or when some one executes open "myapp://hello"
I am new to apple script so I searched a lot but was unable to conclude with a working code snippet.
I tried :
on open location this_URL
display alert this_URL
tell application "Terminal"
reopen
do script "echo 'hello " & this_URL & "'"
activate
end tell
end open location
Updated the Info.plist as:
.....
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
....
This code just opens a terminal but doesn't runs the echo command.
Standalone parts of code :
on open location this_URL
display alert this_URL
end open location
and
tell application "Terminal"
reopen
do script "echo 'hello " & this_URL & "'"
activate
end tell
Works perfectly.
But the combination doesn't work....
Please tell me some workaround.
Thanks in advance
I think this is problem with authorization.
I don't know why but when we add CFBundleURLTypes in plist then macOS prevents us to send events to terminal.
So here is a workaround :
Make 2 apps instead of one as follows
App 1 : url handler
So this will handle the incoming url copy it to clipboard and initiate the 2nd app.
Its applescript will be as follows :
on open location this_URL
set the clipboard to this_URL
tell application "/path/to/app2.app" to activate
end open location
Add CFBundleURLTypes to its plist
App 2 : Terminal handler
It will read the url from clipboard and then run it on terminal.
Its applescript will be as follows :
tell application "Terminal"
set this_URL to ( the clipboard as text )
do script "echo 'hello " & this_URL & "'"
activate
end tell
set the clipboard to ""

Launch shell script on login in Mac OS (OS X)

I have this shell script Test.sh:
#! /bin/bash
FILE_TO_CHECK="/Users/test/start.txt"
EXIT=0
while [ $EXIT -eq 0 ]; do
if [ -f "$FILE_TO_CHECK" ]
then
/usr/bin/java -jar myapp.jar
EXIT=1
else
sleep 30
fi
done
I need to start this script automatically after login.
So I put it inside a folder Test in /System/Library/StartupItems/
When I reboot the Mac, nothing happens after I log in.
Any clue?
I also tried Automator, but with the same result: the java program is not running.
Ivan Kovacevic's pointers, especially the superuser.com link, are helpful; since at least OS X 10.9.2, your options for creating run-at-login scripts are:
Note: The methods are annotated with respect to whether they are:
specific to a given user ("[user-SPECIFIC]"); i.e., the installation must be performed for each user, if desired; scripts are typically stored in a user-specific location, and root (administrative) privileges are NOT required for installation.
effective for ALL users ("[ALL users]"); i.e., the installation takes effect for ALL users; scripts are typically stored in a shared location and root (administrative) privileges ARE required for installation.
The scripts themselves will run invisibly, but - with the exception of the com.apple.loginwindow login-hook method - you can open applications visibly from them; things to note:
There is no guarantee that any such application will be frontmost, so it may be obscured by other windows opened during login.
If you want to run another shell script visibly, simply use open /path/to/your-script, which will open it in Terminal.app; however, the Terminal window will automatically close when your script terminates.
Automator [user-SPECIFIC]:
File > New, type Application
Add a Run Shell Script action, which adds an embedded bash script, and either paste your script code there or add a command that invokes an existing script from there.
Save the *.app bundle and add it to the Login Items list in System Preferences > User & Groups > Login Items.
Note:
The embedded script runs with the default "C" locale.
$PATH is fixed to /usr/bin:/bin:/usr/sbin:/sbin, which notably does NOT include /usr/local/bin
The working dir. is the current user's home directory.
com.apple.loginwindowlogin hook [ALL users - DEPRECATED, but still works]:
If you have admin privileges, this is the easiest method, but it is DEPRECATED, for a variety of reasons (security, limited to a single, shared script, synchronous execution); Apple especially cautions against use of this mechanism as part of a software product.
Place your script, e.g., Test.sh, in a shared location - e.g., /Users/Shared - and make sure it is executable (chmod +x /Users/Shared/Test.sh).
From Terminal.app, run the following:
sudo defaults write com.apple.loginwindow LoginHook /Users/Shared/Test.sh
Note:
The script will run as the root user, so exercise due caution.
Among the methods listed here, this is the only way to run a script as root.
There's only one system-wide login hook.
Note that there's also a log-OUT hook, LogoutHook, which provides run-at-logout functionality - unlike the other approaches.
The login-hook script runs synchronously before other login actions, and should therefore be kept short.
Notably, it runs before the desktop is displayed; you cannot launch applications from the script, but you can create simple interactions via osascript and AppleScript snippets (e.g., osascript -e 'display dialog "Proceed?"'); however, any interactions block the login process.
The script runs in the context of the root user and he username of the user logging on is passed as the 1st argument to the script.
The script runs with the default "C" locale.
$PATH is fixed to /usr/bin:/bin:/usr/sbin:/sbin, which notably does NOT include /usr/local/bin
The working dir. is /.
launchd agents:
launchd-agent-executed scripts can be installed for a SPECIFIC user OR for ALL users - the latter requires administrative privileges.
While using launchd is Apple's preferred method, it's also the most cumbersome, as it requires creating a separate *.plist configuration file.
On the upside, you can install multiple scripts independently.
Note:
No specific timing or sequencing of launchd scripts is guaranteed; loosely speaking, they "run at the same time at login"; there is even no guaranteed timing between the user-specific and the all-user tasks.
The script runs with the default "C" locale.
$PATH is fixed to /usr/bin:/bin:/usr/sbin:/sbin, which notably does NOT include /usr/local/bin
The working dir. is / by default, but you can configure it via the .plist file - see below.
The script-file path must be specified as a full, literal path (e.g., /Users/jdoe/script.sh; notably , ~-prefixed paths do not work.
For a description of all keys that can be used in *.plist configuration files, see man launchd.plist.
Both user-specific and all-users tasks run as the current user (the user logging on).
launchd [user-SPECIFIC]:
Note: Lingon 3 ($5 as of early 2014) is a GUI application that facilitates the process below, but only for user-specific scripts.
Place your script, e.g., Test.sh, in your home folder, e.g., /Users/jdoe
Create a file with extension .plist in ~/Library/LaunchAgents, e.g., ~/Library/LaunchAgents/LoginScripts.Test.plist, by running the following in Terminal.app:
touch ~/Library/LaunchAgents/LoginScripts.Test.plist
Open the file and save it with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<!-- YOUR SELF-CHOSEN *UNIQUE* LABEL (TASK ID) HERE -->
<string>LoginScripts.Test.sh</string>
<key>ProgramArguments</key>
<array>
<!-- YOUR *FULL, LITERAL* SCRIPT PATH HERE -->
<string>/Users/jdoe/Test.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
The <!-- ... --> comments indicate the places to customize; you're free to choose a label, but it should be unique - ditto for the .plist filename; for simplicity, keep the label and the filename root the same.
From Terminal.app, run the following:
launchctl load ~/Library/LaunchAgents/LoginScripts.Test.plist
Note that, as a side effect, the script will execute right away. From that point on, the script will execute whenever the CURRENT user logs on.
It is not strictly necessary to run launchctl load -- since, by virtue of the file's location, it will be picked up automatically on next login -- but it's helpful for verifying that the file loads correctly.
launchd [ALL users]
Place your script, e.g., Test.sh, in a SHARED location, e.g., /Users/Shared
Create a file with extension .plist in /Library/LaunchAgents (requires admin privileges), e.g., /Library/LaunchAgents/LoginScripts.Test.plist, by running the following in Terminal.app:
sudo touch /Library/LaunchAgents/LoginScripts.Test.plist
Open the file and save it with the following content (make sure your text editor prompts for admin privileges on demand; alternatively, use sudo nano /Library/LaunchAgents/LoginScripts.Test.plist):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<!-- YOUR SELF-CHOSEN *UNIQUE* LABEL (TASK ID) HERE -->
<string>LoginScripts.Test.sh</string>
<key>ProgramArguments</key>
<array>
<!-- YOUR *FULL, LITERAL* SCRIPT PATH HERE -->
<string>/Users/Shared/Test.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
The <!-- ... --> comments indicate the places to customize; you're free to choose a label, but it should be unique - ditto for the .plist filename; for simplicity, keep the label and the filename root the same.
From Terminal.app, run the following:
sudo chown root /Library/LaunchAgents/LoginScripts.Test.plist
sudo launchctl load /Library/LaunchAgents/LoginScripts.Test.plist
Note that, as a side effect, the script will execute right away. From that point on, the script will execute whenever ANY user logs on.
It is not strictly necessary to run launchctl load -- since, by virtue of the file's location, it will be picked up automatically on next login -- but it's helpful for verifying that the file loads correctly.
You can't just place plain scripts in that folder. You need a "specialized bundle" how Apple calls it, basically a folder with your executable, and a .plist configuration. And you should put it in /Library/StartupItems since /System/Library/StartupItems/ is reserved for the operating system. Read all about it here:
https://developer.apple.com/library/mac/documentation/macosx/conceptual/bpsystemstartup/chapters/StartupItems.html
Also note that the whole stuff is marked as deprecated technology. And that Apple is suggesting the use of launchd. There is an example how to set it up here:
https://superuser.com/questions/229773/run-command-on-startup-login-mac-os-x
launchd-oneshot is used to install script as a launchd job to run on login, with
brew install cybertk/formulae/launchd-oneshot
sudo launchd-oneshot Test.sh --on-login
Disclosure: I am the author of this package.

Run applescript in Automator

I need to start and stop a small server with automator but my knoledge is very limited. I can't manage to set the path where the file is and I don't know how to stop the server.
So far I have this:
on run
set r to display dialog "Start or stop the NINJAM server ?" buttons {"Stop", "Start"}
if button returned of r is "Start" then
#tell application "Terminal"
# activate
do shell script "cd \"/Applications/ MUSIC/ Utilities/Audio IP/NINJAM/NINJAM/NinjamOSXServer ./ninjamsrv Server.cfg\""
#end tell
else
do shell script "Stop"
end if
end run
Any help is really apprectated. Thanks in advance.
NOTE that I'm using my own path here -- I put the ninjam server folder in the top level of my Applications folder.
I had to create a 'term' file, which is a text file with this in it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WindowSettings</key>
<array>
<dict>
<key>ExecutionString</key>
<string>cd /Applications/NinjamOSXServer/;./ninjamsrv config.cfg</string>
</dict>
</array>
</dict>
</plist>
I saved this as LaunchNinjamSrvr.term and put it in the same folder as the ninjamsrvr. Then the script to use is:
set r to display dialog "Start or stop the NINJAM server ?" buttons {"Stop", "Start"}
if button returned of r is "Start" then
do shell script "open /Applications/NinjamOSXServer/LaunchNinjamSrvr.term"
else
do shell script "killall -INT -v ninjamsrv"
end if
[Occurs to me that I should give some explanation. Directly using the full path with the " config.cfg" parameter makes 'do shell script' choke. Splitting into two commands (but still using do shell script), like you see in the .term file, works to launch ninjamsrv, but makes the script editor (I use Smile) freeze. So that is (presumably -- I didn't want to test it by other means [script app, etc.]) a problem, and why I resorted to using the .term file. It used to be that you could, from the File menu in Terminal (as I recall), save a .term file directly, but that seems to have fallen by the way-side. So, at this point, I have a template that I use and just paste commands into the appropriate line. (But see http://discussions.apple.com/thread/3139585?start=0&tstart=0 -- wherein the technique of exporting Terminal Preference file is explained). I'm being a bit lazy in that the new form is .terminal, not .term ... anyway ...
So now all that is left is doing the actual AS script. 'open' is a basic command line command which is just like opening or double-clicking in the Finder. If, for some reason your file opens in the wrong app or doesn't open, you might need to map it to Terminal.app (in the get info window) and/or change the extension to the more up--to-date '.terminal'.
killall is like kill, designed to kill processes in various ways. I chose -INT because this is essentially like doing a control-c to interrupt the process.]

Mac OS X / Open terminal with specified windows

Is it possible to open a terminal window with 3 tabs. Each tab should have different path.
Example:
Tab1: /etc
Tab2: /bin
Tab3: /www/ tail -f file.txt
This is absolutely possible, but it will take some work on your part. The first thing you need is to set up each window/tab you want in your Settings:
I have 4 tabs that I open automagically every time I open Terminal. DB Shell, Editor, Server, and Shell. These are all within the Sasquatch (don't ask) project, thus the naming. Each of these should then have a unique command associated with them:
In this case, I'm executing vim. If you happen to have a specific directory you'd like to start off in, you can use something like vim ~/projects/main/. Really whatever you want to go in there is the command the shell will execute when it opens. Now you need to open all your windows/tabs:
Close everything.
Open a new window for each of your profiles.
Go to the Shell menu => New Tab/New Window => Select the profile you created above.
Repeat for each window or tab you want.
Once you have all of your windows and/or tabs open, save them as a Window Group.
Go to the Window menu => Save Window As Group....
Give your Window Group a name (this is helpful later).
If you want this group to open every time you open Terminal, check the box at the bottom of this screen, and then hit save.
Close out of all of your Windows/Tabs (time to test it!).
Open your new Window Group.
Go to the Window menu => Open Window Group => Select the group you just made.
This should pop up all the windows you just had, in the same position. Each of the commands you set up in Settings should be launched in their respective tabs.
As of Mac OS X Lion 10.7, Terminal makes this much easier to do, without creating new profiles for each command.
By default, Terminal will remember and restore the current working directory for each terminal in a Window Group. (If the working directory has been communicated to Terminal using an escape sequence. The default shell, bash, will do this at every command prompt. For other shells, you'll need to adapt the code in /etc/bashrc.)
If you create a terminal with Shell > New Command, Terminal will automatically run that command when a Window Group is opened. Terminal will automatically run a limited set of "safe" commands†, and when saving a Window Group there's an option to run all commands in the group.
Terminal also automatically does these for all windows when restarting Terminal with Resume enabled. So, you may not even have to create a Window Group, depending on your circumstances.
For your example case:
Use Shell > New Command to run "tail -f /www/file.txt".
Create a new tab and "cd /etc".
Create a new tab and "cd /bin".
Save them with Window > Save Windows as Group. Be sure to check the "Restore all commands" checkbox.
Each time you open that Window Group, it will recreate those windows and run the commands. If you need to run a command and specify the starting directory, in the New Command dialog check the "Run command inside a shell" checkbox and make the command "cd ; ".
Also note that you can tell Terminal to open your Window Group at startup with Terminal > Preferences > Startup > On startup, open > Window group. There's even a checkbox to set this when saving a new Window Group.
† The "safe" commands include anything listed in /etc/shells, plus: screen, tmux, emacs, vi/vim, nano, pico, and top. You can customize the list with "defaults write com.apple.Terminal RestorableCommands". Set it to an array of strings containing command names or full paths. Some commands have parameters that are "unsafe" to run automatically without user intervention, so by default these commands are only considered "safe" if they do not have any arguments. To make a command safe to run with arguments, add an asterisk, e.g., "top *" is in the default value for this preference.
You can do what you wish from within Terminal.
If in Terminal preferences (Settings tab) you create a new profile (or copy one with Duplicate Settings), you can then set each profile to run a command on startup (the "Shell" subgroup within the profile).
Then setup your tabs by using the Shell > New Tab menu to create the new tabs from each of the specific profiles that you created for the three different executables.
Then do the Save Window Group to save the group of tabs (and it will save their profiles as well).
I suggest the use if iTerm instead of Terminal. If only because it is more configurable. You can script it, but more important to you is that you can create a bookmark folder (one for each tab) and then "open in tabs" which will give you the behavior you seek.
I suspect you can control commands to be executed too. One of the programs I use creates a single-tab terminal window and arranges to execute a profile-setting script before continuing to the command prompt - the same should be feasible for a multi-tab terminal. The file is a MacOS X properties XML file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CommandString</key>
<string>. /Applications/IBM/informix/demo/server/profile_settings</string>
<key>FontAntialias</key>
<false/>
<key>RunCommandAsShell</key>
<false/>
<key>ShowShellCommandInTitle</key>
<true/>
<key>TerminalType</key>
<string>xterm</string>
<key>WindowTitle</key>
<string>IDS Command Window</string>
<key>name</key>
<string>IDS Command Window</string>
<key>type</key>
<string>Window Settings</string>
</dict>
</plist>
You can click on it and the terminal window is launched, the profile settings are set, and then you have a command prompt to type at. Presumably, changing the 'dot' command into the 'tail' command of the question would work; it might be that the 'RunCommandAsShell' key set to '<true\>' would replace the normal shell with the command - which is perhaps more appropriate for the question.
Another way of doing this is by using the Elscripto ruby gem: https://github.com/Achillefs/elscripto. It allows yuo to easily specify terminal tabs using a YAML file
Open the tabs you want and set each one up as you wish, i.e. in tab 1, cd /etc, tab 2 cd /bin and so on. Now go to Window > Save Windows as Group. Click the checkbox 'Use window group when Terminal starts' and hey presto!
http://www.iterm2.com/#/section/features/split_panes
"Divide a tab up into multiple panes, each one of which shows a different session. You can slice vertically and horizontally and create any number of panes in any imaginable arrangement."
How to Create Custom iTerm2 Window Arrangements
Create a custom keyboard shortcut to automatically spawn a set of windows and splits with processes running.
With a shortcut cmd+shift+w transform split your window arrangement into 3 panels
https://www.youtube.com/watch?v=Rg8AT-nds1Q

Resources