Using the Shell (command) and Exiftool

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Using the Shell (command) and Exiftool

Post by Simon Knight » Fri Jan 17, 2025 5:25 pm

Hi all,

I have just spent the day trying to use Exiftool from a Livecode application. I now suspect that there is a flaw in my understanding of how "things" should be working so am asking for my home work to be marked.

I am writing in Livecode v10 running on a mac M2 under OS Sonoma. Exiftool is a well established command line tool written by Phil Harvey see https://exiftool.org/install.html . I have installed the latest version on my mac and am able to access it using the terminal and the default zsh. So far so good.

My longterm goal is to include Exiftool with built versions of my application so I copied the Exiftool folder into my project folder with the intention of using the standalone settings copy file/folders once I come to build the application. However, while I am working on it I want to be able to run tests so need to have it access Exiftool from the IDE.

Its worth looking at and extract from the Readme that comes with Exiftool:
The exiftool script is a command line application. You run it by typing
commands in a terminal window. The first step is to determine the name of
the directory where you downloaded the ExifTool distribution package.
Assuming, for example, you downloaded it to a folder called "Desktop" in
your home directory, then you would type the following commands in a
terminal window to extract and run ExifTool:

cd ~/Desktop
gzip -dc Image-ExifTool-13.12.tar.gz | tar -xf -
cd Image-ExifTool-13.12
./exiftool t/images/ExifTool.jpg
I have followed these instructions and they work from the terminal but I get nothing when running in the IDE.

My test application has a stack with three fields and a button. The fields are names Path, Command and Result. The button has the only code which is here:

Code: Select all

on mouseUp pMouseButton
   put empty into field "Report"
   
   put field path into tPath
   --set the defaultfolder to tPath
   set the shellcommand to tPath
   
   ## Read in the text of the shell command
   put  field "command"  into tCommand
   
   /* test code that issues a standard terminal command and works */
   --set the shellcommand to "/bin/sh"
   --put "say hello from Live code" into tCommand
   
   put shell(tcommand) into tResult
   put "The full command is :" & cr & tCommand & cr & cr after field "report"
   put "Returns :" & cr & tResult & cr after field "report"
   
   put "'It' is set to: " & it after field "report"
   put cr & the result after field "report"
   
end mouseUp
I am aware that shell commands are sensitive to illegal characters in file paths and I have tried wrapping path in single/ double quotes. At times the IT variable is being set to 255 which suggests an error yet the "the result" remains empty.

I am wondering if I have either misunderstood how I should be accessing Exiftool from the IDE or that there is some obscure permissions issue that is not being reported back.

Any thoughts?

S
best wishes
Skids

PaulDaMacMan
Posts: 683
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: Using the Shell (command) and Exiftool

Post by PaulDaMacMan » Fri Jan 17, 2025 11:38 pm

Maybe you need to either change the defaultFolder to where your command line app is before using it, or alternatively use quotes around the full path, "path/to/the/CLI/binary" too (not just around the filename parameters).
Exit code 255 you're getting returned is a vague error, but maybe it could be a permissions related problem (Sonoma).
My GitHub Repos: https://github.com/PaulMcClernan/
Related YouTube Videos: PlayList

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Using the Shell (command) and Exiftool

Post by Simon Knight » Sat Jan 18, 2025 4:12 am

#Paul
Thanks you were correct that it was an issue with paths. I found this thread from a few years ago viewtopic.php?t=37525#p220183 where a link to a python script is described which helped me understand the settings to use to call executables on the system.

I also discovered that it is wise to read the plain text of fields if the text is being used as a command as I suspect the unicode causes issues.

Here is my amended and working button code :

Code: Select all

on mouseUp pMouseButton
   getStackPath  -- sets the default folder to the exiftool folder
   put empty into field "Report"
   
   ## Read in the text of the shell command
   put  the PlainText of field "command"  into tCommand
   ## command from README file : ./exiftool t/images/Exiftool.jpg
   
   put shell(tcommand) into tResult
   put "The full command is :" & cr & tCommand & cr & cr after field "report"
   put "Returns :" & cr & tResult & cr after field "report"
   
   put "'It' is set to: " & it after field "report"
   put cr & the result after field "report"
   
end mouseUp

command getStackPath
   
   -- returns the path for this stack and places the
   -- result in the variable tStackFolder
   
   local tStackFile, tStackFolder
   put the effective filename of this stack into tStackFile
   set the itemDelimiter to "/"
   put item 1 to -2 of tStackFile into tStackFolder
   
   put "/Image-ExifTool-13_12" after tStackFolder
   set the defaultFolder to tStackFolder
   
end getStackPath
The exiftool folder is in the same folder as the stack file and is named "Image-ExifTool-13_12" which gets set as the default folder in the code above.

I think the summary of the command shellCommand in the dictionary is confusing:
Specifies the name and location of the command used for the shell function.
It should be the name and location of the shell application.

This also seems misleading :
Use the shellCommand property to execute a command with a particular shell.
The shellCommand is a property and does not execute anything. Execution of a command using the specified shell is completed by the function Shell.

The following paragraphs are more accurate:
When you use the Shell function, the command line you specify is sent to the program specified in the livecode property shellCommand.

On OS X and Unix systems, the shellCommand is the path to an executable file. On Windows systems, the shellCommand is a DOS command.
So in summary I believe the following is correct :
The shellCommand is a property and does not execute anything. Execution of a command using the shell set in the shellCommand property is completed by the function named Shell.

Whereas the dictionary entry for Shell is clearer if only I had read and understood it (Doh!)
The commandLine must be a valid shell command on the current operating system. Use the shellCommand property to set the shell you want to use. The command is executed in the current defaultFolder.
Where commandLine is a string which I believe may include a folder path that starts from the default folder: thats some experimentation for tomorrow!

S
best wishes
Skids

Simon Knight
Posts: 919
Joined: Wed Nov 04, 2009 11:41 am

Re: Using the Shell (command) and Exiftool

Post by Simon Knight » Sat Jan 18, 2025 3:04 pm

I have finally managed to build a standalone that uses exiftool. However there were several bumps along the way which I detail below in the hope that others will not have to spend so much time seeking work arounds.

My aim was to produce a standalone that had exiftool bundled with it. Reading the Livecode documentation it appears that it should be simple: just add the exiftool folder in the Copy Files tab of the standalone setting page and bingo it will be included in the next build. Wrong, a number of issues came to light and as yet I have been unable to get Livecode to add the folder during the build process.

The first issue was a naming issue in that the folder name contained a full stop; this caused the build to just stop.
Next the folder contained some dot exe files and the copy stopped once it had copied these across.

My solution was to only include the necessary files for use on mac OS. I based this on what was installed in my usr/local/bin folder. I copied these (based on a date search) into a new folder. I added this new folder to the Copy Files tab and saved the standalone. The app built without any reported errors but on inspection the exiftool folder was missing from the package. In the end I had to manually copy the folder into the correct location (Contents/MacOS) and much to my surprise it both opened ok and used exiftool to display data.

Reading other posts indicates that Copy Files has a long history of not working very well, so much so I wonder if most people are just adding files by hand. I am worried that doing this will cause issues with code signing and all the other Apple safety features that can kick in and spoil the fun but so far so good.

S
best wishes
Skids

PaulDaMacMan
Posts: 683
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: Using the Shell (command) and Exiftool

Post by PaulDaMacMan » Wed Jan 22, 2025 2:20 am

Simon Knight wrote:
Sat Jan 18, 2025 4:12 am
#Paul
Thanks you were correct that it was an issue with paths. I found this thread from a few years ago viewtopic.php?t=37525#p220183 where a link to a python script is described which helped me understand the settings to use to call executables on the system.
Glad if it helped and you're welcome.
I think the summary of the command shellCommand in the dictionary is confusing:
Specifies the name and location of the command used for the shell function.
It should be the name and location of the shell application.

This also seems misleading :
Use the shellCommand property to execute a command with a particular shell.
The shellCommand is a property and does not execute anything. Execution of a command using the specified shell is completed by the function Shell.

The following paragraphs are more accurate:
When you use the Shell function, the command line you specify is sent to the program specified in the livecode property shellCommand.

On OS X and Unix systems, the shellCommand is the path to an executable file. On Windows systems, the shellCommand is a DOS command.
No you've got that wrong, the shellCommand should be the path to which CLI shell binary itself, not the command line app you are running from that CLI shell.

On macOS that would be the path to the BASH (/bin/bash) or ZSH (/bin/zsh) shell (depending on macOS version) and there may be others (/bin/csh, /bin/dash, /bin/ksh, /bin/sh, or /bin/tcsh). I believe you can change which shell to use from macOS Terminal.app's preferences. It's much the same on Linuxes ( MacOS X+ and Linuxes are both Unix-like / POSIX compliant). On Windows I think that would be path to 'COM'mand shell or the newer 'PowerShell' maybe (I've never been much of a Windows users).

So when you run a command line the shell script is being interpreted by one of those shells binary executables which can then be used to launch other child-processes such as Exiftool, among other things (typically a shell has some built-in tools).
BASH man page:
https://www.gnu.org/software/bash/manua ... ltins.html
I've read that Apple switched the default to ZSH from 10.15 on because they didn't like open source license GPLv3 which Bash switched to in recent versions. https://support.apple.com/en-us/102360
ZSH docs:
https://zsh.sourceforge.io/Doc/Release/zsh_toc.html
My GitHub Repos: https://github.com/PaulMcClernan/
Related YouTube Videos: PlayList

Post Reply