8

I want to create a service using Automator to run a shell script on all files in a folder, say delete all log files. What I have done is

  1. Created a new service in automator.
  2. Added a "Run Shell Script" action. I have change this to 'pwd' for now.
  3. Selected "Service receives selected folders".
  4. Tried to run it, but get a message. "To test this service within Automator, add the "Get Specified Finder Items" action to the beginning of your workflow. Remove or disable the action before running the workflow outside of Automator.
  5. OK. So I add "Get Specified Finder Items". Added a 'test' directory to the list of items.

Now, when I run the script, the results window prints out my home directory.

Elsewhere, I have read that I maybe need to add

cd "$1"

to the beginning of my script. I did that but it still prints my home directory. How do I get this thing to print the directory I have selected in "Get Specified Finder Items?"

Edited to Add

Here is a screen shot of a script that works.

test

Here is a screen shot os a script that doesn't work.

enter image description here

The usual way I would deal with the "no match found : *.log" error would be to redirect error output to null. Replacing the "rm" line by

find . -name "*.log" -print0 | xargs -0 rm -rf

Does work though. This seems more difficult than it should be.

1
  • I'v updated my answer to show you a working example, have a look and let me know if you have any questions. Mar 25, 2016 at 16:05

1 Answer 1

8

If you're creating a Service using RunShell Script which you want to pass the selected Folder(s) to the RunShell Script and have additional actions take place in the script on them, then start with these settings.

Create the Service:

  1. Open Automator and select Service or File > New > Service If Automator is already open.

  2. Set Service receives selected to folders and in to Finder.

  3. Add a Run Shell Script Action, setting Shell: to /bin/bash and Pass input: to
    as arguments. This changes the default code to from cat to:

     for f in "$@"
     do
         echo "$f"
     done
    

Now you can use $f to act on the target Folder(s), e.g. cd $f and now you're in the directory of $f and can add additional code to act upon the files/folders within $f, etc.

Update:

Use the following working code as an example:

for d in "$@"; do
    cd "$d" || exit
    for f in *.log; do 
        [ -f "$f" ] || continue   
        rm "$f"
    done
done

Within the Test and Test copy folders there were a number of .log files and files with other extensions as well. When the above code was run it deleted only the *.log files within the target folders as show in the images below using two folders or one folder and both files and folders with/without spaces in their names.

Note: The screen shots below do not contain the error handling that was added to the example shell script code per comments to this answer.


enter image description here


enter image description here

6
  • 1
    Thanks. That works. The bit I was missing was "Pass input: as arguments". However, when I add the lines cd $1, rm *.log 2>/dev/null fails with an error "Run Shell Script failed - 1 error" and nothing more enlightening.
    – pheon
    Mar 24, 2016 at 13:58
  • @pheon, Trying to troubleshoot someone's code without a proper mcve is difficult. Also when using a Run Shell Script, there should be no need to use redirects like 2>/dev/null. If you're trying to cd to the Folder passed to the Automator Service you should be using the for loop and cd $f`` as I said, not cd $1`. Read the mcve and add additional information to your question so as to enable proper troubleshooting, otherwise there is not much I can do. You also need to add a screenshot of code being used as it's written in your Automator service. Mar 24, 2016 at 14:56
  • This fails for me if there are no .log files in the folder.
    – pheon
    Apr 1, 2016 at 13:08
  • @pheon. Please understand that code provided is example/sample code and is often minimal to show that something can work. The onus is on the user to write appropriate error checking code and implement it. I'll look at it sometime this weekend and modify/add error checking to the existing example/sample code . Apr 1, 2016 at 19:04
  • I appreciate that it is more complicated than I first thought. I admit I thought it was going to be easy. I was using this as an exercise in learning automator. The frustrating thing is that a bash shell script that works from the terminal does not translate directly into automator and automator does not give useful diagnostic messages when that script fails. Thanks for your help. From here, it is only necessary to help solve the problem if you enjoy the puzzle; I'll find a work around by using the bash script as intended.
    – pheon
    Apr 2, 2016 at 15:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .