Automator: "run shell script" action only receives 1st line of input - macos

I have a weird looking problem (a similar one was asked here, but I don't want to accept that Automator only pipes only 1 line into the shell script action!: Mac Automator: shell script gets only one line)
Automator-Workflow, type "service", 3 blocks:
Service receives "Text"
"run shell script", "bash", input via "stdin", shell script: "cat"
copy to clipboard"
When I select a multiline text and run this service only the first line finishes in the clipboard.
I made three other tests:
skip the shell script action - directly move the selection into the clipboard >> works!
instead of taking the input from the text selection the shell script action gets the input via an "read from clipboard" action from the clipboard >> fails (first line only)
instead of the "bash" action I selected a "perl" action >> fails (first line only)
So it seems obvious that the run shell script action contains the problem.
But I have used the shell script action (with web-content) many times before with no problems.
Any ideas?
Maybe a problem with encoding and or line-endings?

At least on my Mac, when
start Automator
Choose Type -> Service
save at some name (mine is TestService), then
go to TextEdit
enter some text
select
from the TextEdit's menu: TextEdit -> Services -> TestService
Got to the clipboard the next:
2 ééééééééééé
3 íííííííííí
4 αβγδεζη
5 ЧШЩЪЫЬЭ
6 aaaaaaaaaa
Try exactly the above... ;)

I ran into the same issue. Instead of using the 'copy to clipboard' command I then tried executing another shell script (setting its input to 'stdin') containing only the command 'pbcopy'.
Afterwards line breaks were preserved properly.

Related

Automator launching python script

So I'm trying to have a button in my Excel spreadsheet launch a Python script. Apparently this is only possible on Windows, so on the Mac version people have a workaround where they use Excel to launch an AppleScript which then launches a Python script.
In Automator I've tried selecting Application, and when that didn't work I selected Quick Action, and both times I inserted a 'Run Shell Script' module.
Within that I set the Shell to 'usr/bin/python' and Pass input as 'As Arguments'. Then in the text field I put
do shell script "/Users/user_name/Desktop/integrationtest.py"
and I tried
do shell script "python /Users/user_name/Desktop/integrationtest.py"
When I click Run in the top right of Automator it says
The action “Run Shell Script” encountered an error: “ File "<string>", line 1
do shell script "/Users/user_name/Desktop/integrationtest.py"
^
SyntaxError: invalid syntax”
File "<string>", line 1
do shell script "/Users/user_name/Desktop/integrationtest.py"
^
SyntaxError: invalid syntax
Not too sure what I'm doing wrong - any ideas? Thanks for any help
You are mixing up AppleScript and Shell Script syntax.
The Run Shell Script action syntax is
python /Users/user_name/Desktop/integrationtest.py
The Run AppleScript action syntax is
on run {input, parameters}
do shell script "python /Users/user_name/Desktop/integrationtest.py"
return input
end run
I suggest you to go step by step : first open Terminal application and test that your python script runs fine :
python /Users/user_name/Desktop/integrationtest.py
if OK, then open Applescript Editor and create a script with single line : (in Applescript, some environment settings may be different from usual bash Terminal)
do shell script "python /Users/user_name/Desktop/integrationtest.py"
If again this Applescript test works as expected, then call this Applescript from Excel. The method to call depends of your Excel version: With Excel 2011, use Macscript function, and with Excel 2016 use ApplescriptTask.

How to send a command using AppleScript to terminal one by one and save the output, which is not writable to file anywhere?

So, I have a problem. I have downloaded a program from the web. And it's a command line app. I have written a code, which generated some n-k commands to the app. I have written them into an output file. I can write an app in Python, but it freezes on some of the commands. I have tested them manually and seems like there are two issues:
Commands must be run one-by-one;
Some of the commands give an output like bla-bla-bla, this thing is not written into an output file. So, if I run a command ./app -p /file1 -o /file2 -s -a smth- > /fileOutput.txt The fileOutput.txt is empty, though in the terminal, there's is this bla-bla-bla message, stating, that something is wrong. If the command gives bla-bla-bla the app may freeze for a while.
Here is what I want to do:
CD into folder, the containing app;
For command in fileWithCommands perform command and start the next, only when the previous finishes;
If the command gives message, containing bla-bla-bla (cause it may look like file1 bla-bla-bla), write the command and this strange output into file badOutputs.txt.
Have never done applescript before. However, this's what I've done so far:
set theFile to "/Users/MeUser/Desktop/firstCommand"
set fileHandle to open for access theFile
set arrayCommand to paragraphs of (read fileHandle)
#I have found the previous code here: http://alvinalexander.com/mac-os-x/applescript-read-file-into-list-array-examples
close access fileHandle
tell application "Terminal"
activate
do script "cd /Users/MeUser/Desktop/anApp/"
repeat with command in arrayCommand
do script command
end repeat
end tell
Though there's a problem, if in one window the commands make up a huge queue. Without window 1 cd and the command are in different windows. And I am still unable to save the output.
UPDATE
Did with accordance to #Mark Setchell's recommendations. So now I have such code:
set theFile to "/Users/meUser/Desktop/firstCommand"
set fileHandle to open for access theFile
set arrayCommand to paragraphs of (read fileHandle)
close access fileHandle
repeat with command in arrayCommand
do shell script "cd /Users/meUser/Desktop/App/; " & command
end repeat
To the command I have added the following:
2>&1 /Users/meUser/Desktop/errorOut.txt
However, the apple script says that a mistake of the app is the mistake of the script. I.e.: file corrupted, app fails. I want it to write into error file where has it failed and move to the next command, while the script just fails.
Maybe not a complete solution, but more than a comment and easier to format this way...
First Issue
Your command-line app which writes on the Terminal may be writing to stderr rather than stdout. Try redirecting stderr to the same place as stdout by using
./app -p ... > /FileOutput.txt 2>&1
Second Issue
You cannot do:
do shell script cd somewhere
do shell script do_something
because each do shell script will execute in a separate, unrelated process. So your first process will start - in the default directory like all processes - and correctly change directory and then exit. Then your second process will start - in the default directory like all processes - and try to run your command. Rather than that, you can do this:
do shell script "cd somewhere; do_something"
which starts a single process which changes directory and then runs your command line program there.
Issue Three
Why do you want to send your commands to Terminal anyway? Does the user need to see something in Terminal - seems unlikely because you want to capture the output, don't you? Can't you just run your commands using do shell script?
Issue Four
If you want to keep your normal output separate from your error output, you can do:
./app ... params ... > OutputFile.txt 2> errors.txt
Suggestion 1
You can retain all the errors from all the scripts and accumulate them in a single file like this:
./app .. params .. >> results.txt 2>&1
That may enable you to deal with errors separately later.
Suggestion 2
You can capture the output of your shell script into an Applescript variable, say ScriptOutput, like this, then you can parse it:
set ScriptOutput to do shell script "..."
Suggestion 3
If errors caused by your script are stopping your loop, you can enclose them in a try block like this so they are handled and everything continues:
try
do shell script "..."
on error errMsg
display dialog "ERROR: " & errMsg
end try

How do I make my AppleScript detect when I move its application?

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

Execute a shell command on a file selected in the Finder

I'm a very novice and infrequent applescript experimenter. I've tried for several hours now to learn the individual applescript commands for the following task, but I always run into errors. Perhaps someone much more adept at applescript will find this task easy and quick, and for that I would be very grateful. Here is the task:
I want to be able to manually select a document or file within the finder and then execute the following unix command on that file. I would then store the script under Finder's "Services" menu. The unix command is:
srm -rfv -m path/filename
In my attempts, I assumed that a script that would open Terminal and execute the command would be the way to go, but just couldn't get anything to work. Thank you in advance to any good programmers who can whip out such a script for me.
My tip: Create such services using Automator!
Create a new Service in Automator
Choose "File & Folder" as Input and "Finder"
Add "Run shell script"
Choose "as arguments" as input
Change echo "$f" to your command srm -rfv -m "$f"
Save it as "Safe delete"
From now on, if you select a file inside Finder you will find the option "Safe delete" in the context menu.
Enjoy, Michael / Hamburg
Craig's comment is pertinent, but I am just focus on the script itself, not on the shell command. the script bellow must be saved as Application and each time you drop 1 or more file on its icon, the shell script command will be executed for each file :
on open myFiles
repeat with aFile in myFiles -- repeat loop in case you drop more than 1 file on the icon script
try
do shell script "srm -rfv -m " & (quoted form of POSIX path of aFile)
end try
end repeat
end open
Still make sure that in your shell command 'srm -rfv', the 'v' is necessary because this script will not display any thing ! I don't think so. also I did not display error during remove. what do you want to do with error (like write protect, ...) ?
Update: I missed that the OP wants to create an OS X Service that integrates with Finder. ShooTerKo's answer shows how to do that (and his solution doesn't even require use of AppleScript).
The only potentially interesting thing about this answer is that it demonstrates AppleScript commands to open a file-selection dialog, get the chosen file's POSIX path and run a shell command with it, with some general background information about executing shell commands with do shell script.
Try the following:
# Let the user choose a file via an interactive dialog.
set fileChosen to choose file
# Get the file's POSIX path.
set filePath to POSIX path of fileChosen
# Use the path to synthesize a shell command and execute it.
do shell script "echo srm -rfv -m " & quoted form of filePath
Note:
There's no explicit error handling; if you don't want the script to just fail, you'll have to add error handling (try ... on error ... end try) to handle the case of the user canceling the file selection and the shell command failing (unlikely in this case).
The shell command has echo prepended to it in order to perform a dry run (see its output in Script Editor's Result pane); remove it to perform the actual deletion.
quoted form of is important for ensuring that a string value is included as-is in a shell command (no risk of expansion (interpretation) by the shell).
do shell script will NOT open a Terminal window - it will simply run the shell command hidden and return its stdout output, which is usually what you want. If the shell command signals failure via a non-zero exit code, an error is raised.

Read a text file with Automator.app line by line

I'm a novice at coding so please be patient with me.
I've created a Workflow with Automator (OSX) which works fine. The only issue I have is that I want it to run on a number of inputs (that is as a batch). I've inserted the Loop action but the problem I'm having is about changing the initial input each time.
I would like to use an applescript to automate the insertion of the initial input each time.
I have a TXT file with URLs. With an apple script, I'd like to copy a URL (or a line of text) to clipboard.
In the next iteration I'd like to copy the next URL (or line of text).
Can anyone help?
Thank you!!
You can create one looping workflow (called as LinesToClipboard.workflow) what will
get a line from an text file (not rtf, or doc)
copy the line to clipboard
run your current workflow
loop again for the next line
The workflow:
Create new automator workflow
create a variable
at the bottom find the icon "Show or hide the workflow variables list" and show the workflow wariables (empty)
right click and "New variable..."
name the variable as "LineNumber"
add actions:
Get Value of Variable (LineNumber)
Run Shell Script
shell: /bin/bash
important: change the Pass input to as arguments
add the following content (copy exactly, with all quotes and such):
in the content of script, change the /etc/passwd to the full path of your filename, like /Users/myname/Documents/myfile.txt
at the end of this action the clipboard will contain one line from the file
linenum=${1:-0}
filename="/etc/passwd" # full path of your text-filename
let linenum++
sed -n "${linenum}p" < "$filename" | pbcopy
echo $linenum
Set Value of Variable (LineNumber)
Run Workflow - add your current workflow (or the "ShowClipboard.workflow" - see bellow)
the Wait for workflow to finish should be checked
important The Output menu should be: "Return action input"
Loop
add your count...
Run Shell Script (Ignore this action's input), content one line: echo 0 (This will reset the variable LineNumber to zero, when the loop ends)
Set Value of Variable (LineNumber)
For testing, you can create another workflow, called ShowClipboard.workflow, with an content:
Get Contents of Cliboard
Set Value of Variable (clipval)
Ask for confirmation (and drag the (clipval) to the Message field)
Run the first workflow.
Screenshots (for sure) :)
The second workflow (for testing)
You don't need AppleScript to get the URLs but can directly extract them with Automator by using a shell task. After using the task that's getting contents of a folder (this is a Finder task in Automator), add a shell task as the next task. Make sure you select that the input is send as arguments instead of sending it to stdin. When you have done that you only need something like one of the following shell scripts.
cat $# | egrep -io '\S?(http|https|ftp|afp|smb|mailto|webcal):\S+''
It first read all the files using cat. The $# is a shell variable that contains the arguments collected by the previous task: A list of paths to all files of batch folder. We pipe them to egrep will which will only output the URL filtered by their schemes. If you want to support any scheme (official and unofficial schemes):
cat $# | egrep -io '\S?[A-Z][A-Z0-9+-.]+:\S+'

Resources