Monday, December 22, 2014

#1 2012-08-23 11:37:28 pm

greenyouse
Member
Registered: 2012-03-15
Posts: 10

UNIX executables

Out of pure frustration with not being able to have a key to conveniently make script files into executables, I built this crazy AppleScript.  It will ask a user to select some file and then make a new copy of that file in executable format.  I think it goes a little beyond just the chmod +x because the new executable will have the nice looking UNIX executable icon attached to it.

If the script doesn't output an executable file right away, try opening that file with TextEdit, saving it, and then opening an information window from Finder (+i).  It works most of the time but, since it's horribly hackish, it does miss converting a file every so often. 

The script should be added as an automator service and put on a hotkey to make it easily accessible!    --this is kind of the whole reason for the script

Applescript:

set theExoticCharacters to {" ", "'", "\"", ";", ":", "*"} --expand this list if needed
set theNormalCharacters to {"\\ ", "\\'", "\\\"", "\\;", "\\:", "\\*"} --corrects characters for Terminal

tell application "
Finder"
   set the_file to choose file
   set file_name to (name of the_file)
   set file_name to my remove_extension(file_name)
   set parent_fol to folder of the_file
   set new_file to make new file at parent_fol with properties {name:file_name, kind:"
Unix Executable File"}
end tell

set the_text to read the_file
set new_file to new_file as text

set the open_newFile to open for access new_file with write permission
write the_text to open_newFile
close access the open_newFile
set new_fileName to my renameFile(new_file)
set newest_fileName to my POXIFY_location(new_fileName)

do shell script "
chmod u+x " & newest_fileName & ""

tell application "
Finder"
   open file new_file
   tell application "
System Events"
       keystroke "
s" using {command down}
       keystroke "
w" using {command down}
   end tell
   select file new_file
   tell application "
System Events"
       keystroke "
i" using {command down}
       keystroke "
w" using {command down}
       tell process "
Finder"
           set frontmost to true
           keystroke "
w" using {command down}
       end tell
   end tell
end tell



------------------------------
on remove_extension(this_name)
   if this_name contains "
." then
       set this_name to ¬
           (the reverse of every character of this_name) as string
       set x to the offset of "
." in this_name
       set this_name to (text (x + 1) thru -1 of this_name)
       set this_name to (the reverse of every character of this_name) as string
   end if
   return this_name
end remove_extension

on POXIFY_location(this_name)
   if this_name contains "
:" then
       set this_name to (every character of this_name) as string
       set x to the offset of "
:" in this_name
       set this_name to (text (x + 1) thru -1 of this_name)
       set this_name to (every character of this_name) as string
   end if
   set oldTID to AppleScript's text item delimiters
   repeat with i from 1 to count of "
:"
       set AppleScript's text item delimiters to item i of "
:"
       set theTextBits to text items of this_name
       set AppleScript's text item delimiters to item i of "
/"
       set this_name to theTextBits as text
   end repeat
   set AppleScript's text item delimiters to oldTID
   return this_name
end POXIFY_location

on renameFile(theName)
   global theExoticCharacters, theNormalCharacters
   set oldTID to AppleScript's text item delimiters
   repeat with i from 1 to count of theExoticCharacters
       set AppleScript's text item delimiters to item i of theExoticCharacters
       set theTextBits to text items of theName
       set AppleScript's text item delimiters to item i of theNormalCharacters
       set theName to theTextBits as text
   end repeat
   set AppleScript's text item delimiters to oldTID
   return theName
end renameFile

Offline

 

#2 2012-08-25 08:18:02 am

McUsr
Member
From: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: UNIX executables

Hello.

This is a different take, for other purposes. Not as versatile as yours.

This works from within BBEdit (but just change it to "TextWrangler"), and I go to a long extent of not having to enter a localized file kind, god knows what the kind is in Portuguese for instance! wink

I learned the trick for doing this by reading some articles about file creator codes at Daringfireball.net.
This Daring Fireball: Scripting File and Creator Types and Daring Fireball: Setting Empty File and Creator Types.

Applescript:



-- http://macscripter.net/edit.php?id=154742
-- © McUsr 2012 you may not post this elsewhere, nor put it in a repository.
tell application "BBEdit"
   activate -- maybe invoked from quicksilver
   set the_file to file of window 1
   
   set dialog_result to display dialog ¬
       ¬
           "Make Unix Executable:" buttons {"Cancel", "Chmod"} default button 2 ¬
       with icon note
   
   if button returned of dialog_result = "Chmod" then
       tell text document 1 of text window 1 to close
       set px to quoted form of POSIX path of the_file as text
   else
       error number -128 -- user canceled
   end if
end tell
do shell script "chmod u+x " & px
(*
Apparently file creator codes are still good for something at least in SL
as they obstruct the type identifier setting.
The string of four zeros are necessary as this is what inside an "empty"
File creator and File Type code.
*)

tell application "Finder"
   set file type of file the_file to "0000"
   set creator type of file the_file to "0000"
end tell

tell application "BBEdit"
   activate
   open the_file
end tell

Last edited by McUsr (2012-08-25 09:15:47 am)


Mercurial vcs is a joy to use for scripting.

Filed under: localization, file kind

Offline

 

#3 2012-08-26 01:15:57 pm

linuxcoder
Member
Registered: 2012-08-08
Posts: 3

Re: UNIX executables

I'm confused as to why you'd need to reverse the string - twice.  Can't you get the offset then copy from S(1) to S(n) where S(n) is 1 character before the offset?

What am I missing?

Example:

Applescript:

display dialog remove_extension("filename.txt")

on remove_extension(this_name)
   if this_name contains "." then
       set x to the offset of "." in this_name
       set this_name to (text (1) thru (x - 1)) of this_name
   end if
   return this_name
end remove_extension

Last edited by linuxcoder (2012-08-26 01:24:04 pm)

Offline

 

#4 2012-08-26 02:55:18 pm

DJ Bazzie Wazzie
Member
From: the Netherlands
Registered: 2004-10-20
Posts: 2029

Re: UNIX executables

linuxcoder wrote:

I'm confused as to why you'd need to reverse the string - twice.  Can't you get the offset then copy from S(1) to S(n) where S(n) is 1 character before the offset?

What am I missing?

A file names filename.txt.zip ? The file name is filename.txt and the extension is zip. Unlike bash, I mention this because of your name, AppleScript only has a one direction offset sad

EDIT: an example of what I meant:

Applescript:

removeExtension("filename.txt.zip")

on removeExtension(fileName)
   do shell script "a=" & quoted form of fileName & ";echo ${a%.*}"
end removeExtension

EDIT2:
Don't use POXIFY_location(this_name). It's wrong to do that yourself, let the command POSIX path handle this:

Applescript:


set macintoshPath to "Macintosh HD:Users:you:Desktop:testfile.txt"
set posixPath to POSIX path of macintoshPath

Last edited by DJ Bazzie Wazzie (2012-08-26 03:12:14 pm)


Kind regards

Offline

 

#5 2012-08-26 04:42:54 pm

DJ Bazzie Wazzie
Member
From: the Netherlands
Registered: 2004-10-20
Posts: 2029

Re: UNIX executables

Maybe someone is interested in this simple script:

Applescript:

(* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* DISCUSSION
* This script is designed as an addition to TextEdit.app to write shell script.
* It takes the string value from the fornt most document from TextEdit.app
* The string is stored in a file named shellRunner, located in the temporary folder
* The file's executable flag (with chmod) is set
* The new script file is executed and it's stdout and stderr are redirected to shellrunner_log
* shellrunner_log is located in the temporary folder next to the script
* The log file is also opened in Console.app after it's finished
*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* USAGE: A small tutorial
* 1) Open/launch from your applications folder the application TextEdit.app
* 2) Write in the (front most) document 'echo "Hello World!"' (text between the single quotes)
* 3) Launch this script
*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Revision history:
* 0.4: bash scripts containing more than the maximum allowed characters on the command line can be executed now
* 0.3.1: open the the log file now with console as identifier
* 0.3: Shows errors in the console as well and don't show up as an error in this script
* 0.2: Show result in the console
* 0.1: First working solution:
*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Plans in future releases
* 1) Make it idiot proof: check if there is document open etc...
* 2) Create a property/flag where the results should be opened (script editor, console, terminal)
* 3) Create a dialog wheter you want to run or save the script
* 4) Check for the user privileges of the openend document
* 5) In addition to point 4: Ability to run the script as another user
* 6) preprocessing
*)

property creator : "DJ Bazzie Wazzie"
property version : 0.4

tell application "TextEdit"
   set theSource to text of document 1
end tell

set execFile to (path to temporary items as text) & "shellRunner"
set execLogFile to (path to temporary items as text) & "shellrunner_log"

--0.4 do shell script "/bin/echo -n " & quoted form of theSource " & > quoted form of posix path of execfile
try
   set descriptor to open for access file execFile with write permission
   set eof of descriptor to 0
   write theSource to descriptor as «class utf8»
   close access descriptor
on error m
   close access file execFile
   return m
end try

do shell script "chmod u+x " & quoted form of POSIX path of execFile
--0.3: " > " has been replaced with " &> " to pass messages to stderr to console as well
do shell script quoted form of POSIX path of execFile & " &> " & quoted form of POSIX path of execLogFile
do shell script "open -a console " & quoted form of POSIX path of execLogFile

Last edited by DJ Bazzie Wazzie (2012-08-26 05:00:22 pm)


Kind regards

Offline

 

#6 2012-08-26 05:46:12 pm

linuxcoder
Member
Registered: 2012-08-08
Posts: 3

Re: UNIX executables

DJ Bazzie Wazzie wrote:

linuxcoder wrote:

I'm confused as to why you'd need to reverse the string - twice.  Can't you get the offset then copy from S(1) to S(n) where S(n) is 1 character before the offset?

What am I missing?

A file names filename.txt.zip ? The file name is filename.txt and the extension is zip. Unlike bash, I mention this because of your name, AppleScript only has a one direction offset sad

Didn't know about that.  That seems like a strange omission of [any] programming language.  Makes for more clumsy code than is necessary.  The OP's solution makes more sense, now.  I've only tinkered with Applescript.  Does it have a strings library, or does everyone just roll their own?  I'd definitely code a right_offset() and stick it in.

Offline

 

#7 2012-08-26 07:11:49 pm

McUsr
Member
From: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: UNIX executables

linuxcode wrote:

Does it have a strings library, or does everyone just roll their own?  I'd definitely code a right_offset() and stick it in.

Jon Pugh Has made a smart strings library, Jon Pugh's Home Page.

To your second part, if if it was that  practical to code and use a right_offset() then everyone would have done it.

You'll end up with something like this, which eats cycles, we usually do string handling  by text item delimiters, which considers content more than position. smile

Applescript:



set m to "myfilename is long.txt.zip"

set rofs to right_offset for m by "."

set n to text 1 thru (rofs - 1) of m

-->"myfilename is long.txt"

to right_offset for sToSearch by sString
— McUsr made this handler and put into Public Domain without copyright!
— http://macscripter.net/edit.php?id=154775
   local l1, l2, sofs, tofs, rofs
   
   set l1 to length of sToSearch
   if l1 = 0 then return 0
   set l2 to length of sString
   if l2 = 0 then return 0
   set sofs to offset of (reverse of characters in sString as text) in (reverse of characters of sToSearch as text)
   if sofs = 0 then return 0
   set tofs to sofs + l2 - 1
   set rofs to l1 - tofs + 1
   return rofs
end right_offset

Last edited by McUsr (2012-08-26 07:23:31 pm)


Mercurial vcs is a joy to use for scripting.

Filed under: right_offset

Offline

 

#8 2012-08-26 08:57:10 pm

Shane Stanley
Member
From: Australia
Registered: 2002-12-07
Posts: 3834

Re: UNIX executables

linuxcoder wrote:

That seems like a strange omission of [any] programming language.

While I don't disagree, it helps to understand that AppleScript was never designed as a general-purpose programming language, but rather as a simple user-friendly language to use to drive applications. Of course it's used for tasks way beyond its initial remit, and you can argue that the original idea was somewhat short-sighted. (And of course you can argue that there's been plenty of time to remedy things.) But it's easier to understand what's there if you also understand the intent.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#9 2013-01-04 03:12:28 pm

McUsrII
Member
Registered: 2012-11-20
Posts: 2431
Website

Re: UNIX executables

Here is another idea, with respect to DJ Bazzie Wazzie`s.

This is really work in progress, this one filters the front text document through a shell command in BBEdit, and puts the result in an Output window. I know, you can just undo to bring the previous text back, but sometimes it is ok, to compare before and after, until you have the command right.

I found this at the address inside it, and modified it slightly, I am going to modify it further to work on a selection, when the moment is right.

Applescript:


-- https://groups.google.com/group/bbedit/tree/browse_frm/month/2009-07/688d7289fc320fb3?rnum=21&_done=%2Fgroup%2Fbbedit%2Fbrowse_frm%2Fmonth%2F2009-07%3F

property pPipeCommand : "sort | uniq"

on translate_line_breaks(str)
   set AppleScript's text item delimiters to {ASCII character 13}
   set _lines to every text item of str
   set AppleScript's text item delimiters to {ASCII character 10}
   set str to _lines as text
   set AppleScript's text item delimiters to {}
   return str
end translate_line_breaks

on run
   tell application "BBEdit"
       if not (exists text window 1) then
           display alert "This script requires an open text window."
           return
       end if
       if length of selection of text window 1 is 0 then
           select text 1 of text window 1
       end if
       set _selectedText to selection of text window 1 as Unicode text
   end tell
   
   set _selectedText to translate_line_breaks(_selectedText)
   
   set _tempFilePath to "/tmp/BBEditPipeTemp"
   set _tempFile to open for access (POSIX file _tempFilePath) with write permission
   set eof _tempFile to 0
   set a to write _selectedText to _tempFile as «class utf8» starting at 1
   close access _tempFile
   
   display dialog "Pipe command?" default answer pPipeCommand buttons {"Cancel", "Run"} default button 2
   set pPipeCommand to text returned of result
   
   set _command to "cat " & _tempFilePath & " | " & pPipeCommand
   set _output to do shell script _command
   
   tell application "BBEdit"
       make new text window at front
       set selection of text window 1 to _output
   end tell
end run


Filed under: command, filter, BBedit, unix

Offline

 

#10 2013-11-20 08:03:14 am

McUsrII
Member
Registered: 2012-11-20
Posts: 2431
Website

Re: UNIX executables

Hello.

This is yet another idea, the two scripts are for creating and executing shell scripts with TextEdit, using their own extension "shellscript", so that it is easy to double click on the script files in the finder and either edit or run them, after you have had a look at them. (I like to see them before I run them, if the script is made for a special task, and isn't a subroutine.) The output from a shell script will be redirected to a new open TextEdit document.

You'll need maverick, and The library posted under the title ConsoleIO here in Code Exchange.

The script below executes a shell script that is open in TextEdit.

Edit

You need to have Developer tools installed to use this, since I use the command SetFile.

Applescript:

use AppleScript version "2.3"
use scripting additions
use Output : script "Output"

tell application id "ttxt"
   set docPath to path of its front document
   try
       set probe to docPath
   on error
       display alert "Save AND make executable first..."
       error number -128
   end try
end tell
set shFile to POSIX path of docPath
try
   set theResult to do shell script quoted form of shFile
on error e number n
   display dialog e
end try

if theResult is not "" then Output's initWithText("Output From: " & shFile & linefeed, 600, 800, theResult)
Output's leaveAtFront(0.5)

The script below creates a shell script of the front document in TextEdit and will make it so that it will always open in TextEdit, provided you give the script a ".shellscript" extension.

Applescript:

tell application id "ttxt"
   set docPath to path of its front document
   try
       set probe to docPath
   on error
       display alert "Save first..."
       error number -128
   end try
end tell
set shFile to POSIX path of docPath
set sfxOfs to offset of ".txt" in shFile
try
   if sfxOfs is not 0 then
       set newSFile to text 1 thru (sfxOfs - 1) of shFile
       
       do shell script "mv " & quoted form of shFile & space & quoted form of newSFile & "; chmod u+x " & quoted form of newSFile & "; SetFile -c \"ttxt\" -t \"ttxt\" " & quoted form of newSFile
       set docPath to POSIX file newSFile as alias as text
   else
       do shell script "chmod u+x " & quoted form of shFile & "; SetFile -c \"ttxt\" -t \"ttxt\" " & quoted form of shFile
   end if
on error e number n
   display dialog e
end try


tell application id "sevs" to tell disk item docPath
   set default application of it to "com.apple.textedit"
end tell

Last edited by McUsrII (2013-11-20 08:10:42 am)

Offline

 

Board footer

Powered by FluxBB

[ Generated in 0.045 seconds, 12 queries executed ]

RSS (new topics) RSS (active topics)