Converting terminal command to AS command

Wanting to experiment with a clean zip file, but difficulty attempting at incorporating such a command into AS.

The needed command is
zip -r my_compressed_file.zip path/to/folder -x “*.DS_Store” -x “__MACOSX”

AS does not like the " after the -x I’ve tried adding more " to the command but still no fix.
I’d normally expect the command to start like: try
do shell script "zip …
Any advice appreciated.

Model: mp3,1
AppleScript: 2.8.1
Browser: Firefox 78.0
Operating System: macOS 10.11

Try setting up your paths beforehand. If, for example, you had spaces anywhere then your script would fail just for that but you don’t mention the error you’re actually receiving.

-- path to directory to zip
set dir2zip to POSIX path of (path to desktop as text) & "application exists"
set qd to quoted form of dir2zip

-- path to resulting archive
set zippedFile to POSIX path of (path to desktop as text) & "myc.zip"
set qzf to quoted form of zippedFile

-- do shell script "zip -r " & qzf & space & qd
do shell script "zip -r " & qzf & space & qd & " -x '*.DS_Store' '__MACOSX'"

This is the command that the above sends to the shell:

[format]“zip -r ‘/Users/me/Desktop/myc.zip’ ‘/Users/me/Desktop/application exists’ -x ‘*.DS_Store’ ‘__MACOSX’”[/format]

The man page suggests a necessity to use a backslash to avoid potential filename substitution, so quoting the excluded items might not be desirable; they can also be grouped in a “list.”

do shell script "zip -r " & (((path to desktop)'s POSIX path) & "zip-a-dee-doo-dah.zip")'s quoted form & space & (choose folder)'s POSIX path's quoted form & " -x \\*.DS_Store \\__MACOSX "

The single quotes, i.e. quoted form, prevent the shell from interpreting anything within them.

https://developer.apple.com/library/archive/technotes/tn2065/_index.html#//apple_ref/doc/uid/DTS10003093-CH1-TNTAG3-MY_COMMAND_DOESN___T_WORK_RIGHT_WHEN_A_PARAMETER_HAS_SPACES_OR_CERTAIN_PUNCTUATION_____PARENTHESES________ETC_

Out of curiosity, why escape the first underscore?

You’re right about only requiring a single ‘-x’.

I find that either of these will work, which makes sense to me as they’re both escaping the asterisk. Just having the asterisk also works but then you have the risk of something unforeseen happening.
[format]
-x \.DS_Store
-x '
.DS_Store’[/format]

This doesn’t work but I’m not sure why.
[format]
-x ‘.DS_Store’[/format]

It does appear to work either way—single quoted or slash escaped. In regards to why the last example failed to work, it’s because the whole path, rather than the name, is being evaluated; the asterisk is a wildcard for ‘whatever’ that precedes ‘.DS_Store.’ I didn’t have such a file for testing, but my script’s second list item would actually need to be adjusted to also include an asterisk; e.g. “\*_MACOSX.”

Okay that makes sense. I was thinking that having the filename would be sufficient because it was working the same folder but that’s not the case. I tried working with just the top-level directory (i.e. no recursion). It added all the files but the exclusion failed without the asterisk, even when I ran the command from that directory. Something learned. Thanks.

I guess the last file falls into the same category — I also didn’t have one of those to test.

Finally after a month I’ve started testing this out. For some reason when I unzip the file I end up with a Users/me/Desktop/Users/me/Untitled.txt result. ie: a duplicate user account & desktop folder.

What’s going wrong?

There’s really no difference between my script and yours

-- path to directory to zip
set dir2zip to POSIX path of (path to desktop as text) & "Untitled.txt"
set qd to quoted form of dir2zip

-- path to resulting archive
set zippedFile to POSIX path of (path to desktop as text) & "Untitled.zip"
set qzf to quoted form of zippedFile

-- do shell script "zip -r " & qzf & space & qd
do shell script "zip -r " & qzf & space & qd & " -x '*.DS_Store' -x '__MACOSX'"

I think you have to change the zip options. From the zip man page:

I modified the command line in your script as follows and it did not create the additional path information in my testing:

do shell script "zip -r -j " & qzf & space & qd & " -x '*.DS_Store' -x '__MACOSX'"

Hi
That works with a simple text file. However does not work with the intended target.

error "	zip warning:   first full name: /Users/me/Desktop/program/org/bushe/swing/event/annotation/EventSubscriber.class
                      second full name: /Users/me/Desktop/program/org/bushe/swing/event/EventSubscriber.class
                     name in zip file repeated: EventSubscriber.class
                     this may be a result of using -j

zip error: Invalid command arguments (cannot repeat names in zip file)" number 16

The intended target itself has sub-folders/directories. Error using -j due to more than one file having same file-name (with the directories removed.)

Is it possible to zip the file whilst maintaining the directories structure?

After all, my objective is to actually change a few files within the package, re-zip (cleanly) & change file extension back to jar.

The original error was the entire source/target directory listing becoming a part of the zip. Though I thought you had initially pointed out a possible problem is with the way the source or target was listed — except I think you may have edited out that comment (perhaps I’m wrong.)

Removing the -j command results in that same error of zipping the directory levels above the intended folder as well.

Completely unrelated but please don’t adopt bad practices like

POSIX path of (path to desktop as text) 

The as text coercion is redundant because POSIX path is a property of alias

POSIX path of (path to desktop) 

In order to maintain your expected structure, change the directory.

#Basic (the first quoted item is the parent folder; the third is the subdirectory):

do shell script "cd '/Users/yourusernamehere/Desktop/'; zip -r 'zip-a-dee-doo-dah.zip' 'Test'"

#Fleshed out:

do shell script "folderTarg=" & (choose folder with prompt "Where's the folder to compress?")'s POSIX path's quoted form & "; cd $(dirname $folderTarg); zip -r 'zip-a-dee-doo-dah.zip' " & "$(basename $folderTarg) " & "-x \\*.DS_Store \\*__MACOSX "

#Alternate command:

do shell script "ditto -ck " & ((((path to desktop)'s POSIX path) & "Test")'s quoted form) & space & ((((path to desktop)'s POSIX path) & "zip-a-dee-doo-dah.zip")'s quoted form)

I think that -j flattens the hierarchy, which would create the conflict that’s generating your error.

From this answer https://unix.stackexchange.com/a/236364/309489 on the Unix StackExchange, it looks like you can manage this by feeding zip a relative path.

First, put the target dir in a variable:

set dirName to quoted form of "application exists"

Then change to the target dir and run the command:

do shell script "cd " & qd & ";  zip -r " & qzf & space & "../" & dirName & " -x '*.DS_Store' '__MACOSX'"

So the full command being passed will be:

"cd '/Users/me/Desktop/application exists';  zip -rD '/Users/me/Desktop/myc.zip' ../'application exists' -x '*.DS_Store' '__MACOSX'"

Thanks to everyone for your input.
Now works with those changes (And removing the “as text” reference.) Also tried replacing the “as text” with " folder from user domain as string" & also works but suspect this is unnecessary.

-- path to directory to zip
set qd to quoted form of POSIX path of (path to desktop) & "folder name" -- will error if does not exist.
set dirName to quoted form of "folder name"

-- path to resulting archive
set qzf to quoted form of POSIX path of (path to desktop) & "program sub-folder"

-- do shell script "zip -r " & qzf & space & qd
do shell script "cd " & qd & "; zip -r " & qzf & space & "../" & dirName & " -x '*.DS_Store' '__MACOSX'"

I was amused when peavine mentioned unzip because that was going to be my next question.
For a semi-related issue:

For the unzip process, should change directory command also be used or simply switch the CD command to the initial unzip or unnecessary for unzip?
I’ve used the unzip command in a previous script for different app (& purpose) and it appears to function ok.


	set ZipFile to quoted form of POSIX path of ((path to application support folder from user domain as string) & "program:yyy.zip")
	set ZipLoc to quoted form of POSIX path of ((path to library folder from user domain as string) & "Application Support:program:")
set extract_file_name to "zzz.txt"

	try -- unzip command via Unix.
		do shell script "unzip -o -d " & ZipLoc & space & ZipFile & space & extract_file_name --- unzips file and overwrites if previous zzz file exists.
	end try

But I want to be sure, not hope it works at all times on everyone’s system.

Since applescript 2, ‘as string’ and ‘as text’ are synonymous (although I think that an individual application could define them differently).

In general, ‘path to…’ generates an alias, so if you actually need the text (as opposed to the file reference), then coerce to text. However, as StefanK pointed out, ‘posix path of…’ returns text, so in your example, ‘as string’ is redundant.

Not sure why you use a different ‘path to’ for zipfile and ziploc. The result is the same but it adds unneeded complexity.

set zipLoc to quoted form of POSIX path of (path to application support from user domain)
set zipFile to quoted form of POSIX path of (path to application support from user domain) & "yyy.zip"

-- Alternatively…
set zipPath to POSIX path of (path to application support from user domain)
set zipLoc to quoted form of zipPath
set zipFile to quoted form of (zipPath & "yyy.zip")

As for using an extraction directory (-d), I think that yours is the better approach. However, as Apple introduces new security mechanisms, seemingly with each OS release, you never know when it might break.

Browser: Firefox 96.0
Operating System: macOS 10.12

Thanks for the clarifications. That’s very helpful.

I needed to make changes to that original script after realising it had broken with later OS.

I intend to do the processing outside of the apps folder as I’m sure on some people’s systems there may well be permissions issues or it appears inevitable for future macos in the same way Win 10 limits/prevents changes within the app directory. (But there may well be issues replacing app or app package files ~ I also intend to re-add gatekeeper exception around that point in time.)

It’s awkward guesswork not being able to test these things on the newer computers & OS.

Thanks again for everyone’s help.

Model: mp3,1
AppleScript: 2.8.1
Browser: Firefox 78.0
Operating System: macOS 10.11