Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
Tinderbox Users >> Agent, Actions, Rules & Automation >> Interacting with the Mac shell

Message started by Sumner Gerard on Oct 15th, 2012, 2:30pm

Title: Interacting with the Mac shell
Post by Sumner Gerard on Oct 15th, 2012, 2:30pm

[edit]By admin (mwra). This topic was split from the more specific topic "Re: Useful sed scripts" as it starts to discuss wider interaction beween TB and other apps via the shell.[/edit]

Thanks! This is very helpful to me. (Hope I haven't hijacked thread; it is ultimatedly related to making sed and other commands useful in Tinderbox.)

Without a tech background, my thinking and vocabulary must be unconventional.  I've been assuming a script is a script is a script, whether it's in a Tinderbox code note, in an Automator-generated service, or in a file in a Scripts folder or wherever.  

So for me it has not been either runCommand() or a script (wherever it happens to be). It's been a hybrid of the two.

That combination enables me to pass values into/out of Tinderbox attributes, by one of two approaches:
1 -- run a script via runCommand()
2 -- run an external script that does things and then accesses runCommand() in a stamp by "clicking" a "menu item" in the Stamps "menu".  

For me approach 1 usually works well with scripts stored either in a code note or in an external file. Referring to a script in a code note seemed easy, $Text("NameOfCodeNote"). Figuring out how to give the right path to an external file was a bit more trouble, at least at first.

Approach 2 so far doesn't seem to work with AppleScripts in code notes or scripts run by making a choice from the Scripts menu. But it works reliably in an Automator-created service or as a choice in the FastScripts menu.

So when GUI scripting TB with AppleScript, at least, there seem to be important differences between storing a script in a code note and running via runCommand() vs running it from a script in a file "in some convenient place" outside Tinderbox.

[edit]existing edit, by Mark Bernstein, to @Sumner's post:

I'm fairly sure this is not quite correctly diagnosed.  The key here seems to me to be the question of GUI scripting, which is, I think, wildly esoteric for use with runCommand. I'm scratching my head about what you're trying to do, but (a) it sounds a long way from the things I'd expect to do with runCommand, (b) GUI scripting has nothing to do with sed that I can see, and (c) I'm still pretty much sick as a dog.  So, for now, just a quick placeholder note to say to confused people that the question discussed here is probably very specialized; I think the earlier summary of alternatives remains good.

My impression -- and I may be mistaken here -- is that sed is likely to be the wrong tool for people who are not already sed fans.  Is there an application where, if you had to learn a new software tool to do a job, you'd reach for sed rather than awk, perl, python, or ruby? Nothing against using sed because you're already familiar with it and it does the job. But, if you need to do some text manipulation outside of Tinderbox, learning a smidgen of perl gives you all of sed, and lots more if you need it later.

Title: Re: Useful sed scripts
Post by Sumner Gerard on Oct 15th, 2012, 11:34pm

Sorry to hear about illness. Wish you a fast and full recovery.

I've presented an early example of what I'm "trying to do" here.  Actually I'm not trying to do it; I've already done it. That one case does indeed involve runCommand() and one line of gui scripting. Maybe there is a better way but I couldn't find it. It does work reliably on my machine, and it does something I've found practical and useful, not particularly esoteric.

I have a number of other working examples where (without gui scripting, thankfully) I use runCommand() with osascript... and one challenging encounter with sed, hence my initial interest in this thread (didn't realize awk, perl, python, ruby might provide better tools.) Anyway, by passing values between Tinderbox attributes and AppleScript (often contained in a code note), which then interacts with other apps in the usual Mac way, useful and practical things have become possible. Again, nothing particularly esoteric and not particularly hard. By and by I'll put specific examples in another thread; that very likely will dispel confusion.

Title: Re: Interacting with the Mac shell
Post by Mark Anderson on Oct 16th, 2012, 2:03pm

Having seen your TB-AppleScript round trip example I think you're basically pushing the offered shell access hard in directions I doubt were envisaged by Eastgate. for instance, it's not really intended as a conduit for faking appleScript access.

I think my concept of a 'code note' - originally coined as shorthand for storing TB action code in $Text - has been unintentionally misread as being a deliberate affordance for writing shell scripts. Far from it. The idea of a code note for shell use is:
  • no messing around in a note's $Rule input box (or a stamp) to set up a complex CL.
  • the $Text can be passed direct to runCommand (elsewhere) as a single complete argument string. In some cases the $Text may want to be evaluated first (though again we're now getting in to complex, edge case areas).
IOW, it makes it a lot easier for the non-coder to set up a CL correctly. Because runCommand($Text(Some note)) receives the contents of the $Text of "Some note", we don't need to quote-enclose it in the source $Text. This is important if your CL needs to use both single and double quotes within the CL itself leaving none free for TB string enclosures. This thus routes around a current limitation of TB not being able to escape either quote type within its action/export codes (in this context runCommand() calls are action code).

For more byzantine tasks, I'd recommend using an external shell script and using runCommand to pass it parameters (or a CL via a code note if quote constrained! - but do it explicitly in a shell script. In developing your shell script, I'd suggest starting by echoing back your input parameters to ensure the script is getting the data you expect. If it is the issue becomes one of writing a suitable shell script. If not fix the export string before progressing the script.

I'd accept, the UI-less shell is scary for us Unix neophytes to whom Terminal is somewhat inscrutable. And there's the rub. Just because simple CLs are easily entered into runCommand() it doesn't mean whole scripts can be run by such a method.

As discussed in my post in your AppleScript example, perhaps the issue isn't making complex shell access so much as looking to see if a less fragile option doesn't exist. Many of the shortcut apps are cheap/free. Also don't overlook Automator to create OS services to add some extra custom functionality.

Title: Re: Interacting with the Mac shell
Post by Sumner Gerard on Oct 17th, 2012, 5:11pm

Thanks for the helpful pointers! I pick up valuable little things about quotation and such.

I do understand the code notes were originally intended for Tinderbox action code, not shell scripts. I haven't naturally gravitated to shell scripts anyway. To me a "shell" has been mainly what "she sells by the seashore" and the command line has loomed large in my mind as a window to a mysterious Unix universe best left to experts and masochists.:)

Code notes do seem to be a great place to store short scripts like your quotify sed (I think that qualifies as a "shell script", right?).

While I haven't used code notes for shell scripts (except your quotify and the other one that strips surrounding quotes) I have found code notes to be a handy place to store AppleScripts run by one-line shell scripts within runCommand().  Storing the (succinct by the standards of that language) AppleScripts there means I don't have to worry about path and all that, which can get cumbersome.

Now why on earth would I want to do something so seemingly convoluted as run an AppleScript via a one-line shell script in runCommand()?  Well, to pass values back and forth from/to Tinderbox attributes, of course, just as with any other script run through runCommand().

I haven't yet presented my (to me immediately useful and I suspect useful to some other users too) working examples of how I do that. The encounter with the shell is mercifully brief (as I say one-line) and I suspect not a strain on TB's offered shell access.  Almost all the work is done in AppleScript, which as you know has its defects but does allow the general user like me to interact with other Mac apps in useful ways, and, unlike TB action and export code, offers a friendly debugging environment and numerous examples on the net.

The "Save Name As" example to which you refer is something else entirely. I wonder how that one could "push offered shell access hard." The only thing within runCommand() is a supremely simple one-line script that does nothing but return the contents of the clipboard as Unicode text. That's it.  And all the accompanying (short) AppleScript does is place selected text on the clipboard and then tell the Mac interface to click the Tinderbox menu item that contains the stamp with the simple runCommand().  It's been confusing why that simple sequence has been portrayed as so confusing. :)

Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com) » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.