Do Shell Script "Unexpected Token"

This…

do shell script "/usr/bin/sdiff <(echo 'oneThing') <(echo 'anotherThing')"

…results in the error:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `/usr/bin/sdiff <(echo 'oneThing') <(echo 'anotherThing')'

I understand that that this is due to the default use of the sh shell, but none of Apple’s advice on How do I run my command with a shell other than sh? has achieved anything but more errors. Even writing a bash script to a file and using do shell script to run it fails.

“It’s like I’m loooosing my mind…”

What are the parentheses for?

sdiff should just be fed the files directly, eg:

sdiff oneThing twoThing

Thanks for the lightning reply.

They aren’t files - they’re literals, for demonstration purposes.

The problem is that do shell script runs under sh, under which (for reasons beyond me), sdiff throws an error. It runs fine in terminal under zsh, bash, or anything I’ve tried.

I’ve jumped through all the hoops I can think of, but can’t persuade AppleScript to do shell script in anything but sh. None of Apple’s Suggestions work for me, though perhaps I’m being dense.

Thanks again,
Bryan

That specific error is likely because the parentheses require escaping, which in applescript means double-backslash, eg ‘\\(’.

Of course, if you do that with all of the parentheses, you may find that you get another error.

FWIW, if I use two actual files instead of literals, then I can get the script to run.

set pdt to path to desktop as text
set ppd to POSIX path of pdt
set t1 to quoted form of (ppd & "t1.txt")
set t2 to quoted form of (ppd & "t2.txt")

-- with default shell
set cm to "/usr/bin/sdiff " & t1 & space & t2
-- do shell script cm
--> error "test text 1						      |	test text 2" number 1

-- with alternate shell
do shell script "/bin/tcsh -c '" & cm & "'"
--> error "test text 1						      |	test text 2" number 1

So, I think that one issue is how to present the literals so that they get through to the applescript’s shell intact.

The other issue would be how to deal with the output, which, when there is a difference will generate an error 1. The tech note includes information on how to deal with error output but I haven’t looked at it lately.

Depending on what kind of output you are wanting, Terminal’s do script command works with your example.

Actually when I try to run your command in the terminal, specifically the shell “sh”, I get the. Same error.
So it is not a “do shell script” problem, but an actual shell problem.

Try first fixing it so it works in the sh shell then move on from there

I tested the OP’s shell script in a shortcut using a Run Shell Script action. I did this because this action generally does a good job of running shell scripts and because this action allows you to select the shell used from a drop-down list. The shell script failed no matter what shell I used.

The following script (reference) would seem to indicate that the issue is that sdiff requires actual files, but my skills in this area are too limited to really be certain. BTW, the output option does nothing in this script, but it won’t work otherwise.

set fileOne to do shell script "mktemp -t fileOne"
do shell script "echo \"oneThing\" >> " & fileOne
set fileTwo to do shell script "mktemp -t fileTwo"
do shell script "echo \"anotherThing\" >> " & fileTwo
set theDifference to do shell script "/usr/bin/sdiff -o ~/test.txt " & fileOne & " " & fileTwo
--> "oneThing                                                      | anotherThing
-->%"

Actually not true.

the sdiff command he has runs fine in the standard mac shell
here is the output

“oneThing | anotherThing”

The OP’s command works for me in the terminal also. I don’t have the expertise to know why, but perhaps the terminal makes the necessary temporary files that are required by sdiff but do shell script does not.

When I run the OP’s script in a few shells, the error message is “Missing name for redirect.” Perhaps that’s one of the reasons my script returns the expected results. Anyways, this thread needs a shell expert, which I’m not.

its the shell.

the default mac shell is not “sh”, it’s “zsh”

if you try the command in sh, it fails. It has nothing to do with do shell script.

Alas,

do shell script “/usr/bin/sdiff <\(echo ‘oneThing’\) <\(echo ‘anotherThing’\)”`

fails with

sh: (echo: No such file or directory

Clearly something isn’t getting through.

Just for closure… I’ve settled for a godawful kludge. If I cache the text blocks I’m comparing to files, I’ve discovered that the resulting error includes the correct result.

tell fileLib
	set block1file to Cache_Data from "blah blah blah"
	set block2file to Cache_Data from "whacka whacka whacka" under "format_script"
end tell

try
	do shell script "sdiff " & ¬
		quoted form of block1file & ¬
		space & ¬
		quoted form of block2file without altering line endings
on error errorMessage
	set theResult to errorMessage
end try

if lineNumbersOnly then
	set theResult to do shell script ¬
			"sed -En " & ¬
			"-e '/--/!d' " & ¬
			"-e '/[/||<|>]/='" & ¬
			" <<< " & quoted form of theResult
end if

return theResult

It’s downright embarrassing, but as this is a one-time personal project I’m unlikely to share, you’re the only one who will know my shame. :kissing_cat:

Thanks again for your comments.

Unfortunately, I need it to run using AS’s do shell script.

AS’s do shell script command doesn’t use the default shell. See Apple’s TN2065 for the full explanation.

If you put your ‘do shell script’ code directly into an executable .sh file, you can then run that Shell Script file using the ‘do shell script’ command.

/usr/bin/sdiff <(echo 'oneThing') <(echo 'anotherThing')

I even automated the whole process of creating the executable .sh file and adding the code to that file.

This following animation shows script 1 creating a test.sh (with the shebang) file on my desktop and makes that file executable. Then script 2 pastes your

/usr/bin/sdiff <(echo 'oneThing') <(echo 'anotherThing')

which is on my clipboard, into the test.sh file. The 3rd script in the animation finally runs that ‘do shell script sdiff’ command.

sdiff

This following AppleScript code creates the executable .sh file with the shebang.

activate
set theFile to quoted form of POSIX path of (choose file name)

set theShellScript to "if [[ ! -f " & theFile & "  ]] ;then echo \"#! /usr/bin/env bash\" > " & theFile & " ;chmod 755 " & theFile & " ;fi"

do shell script theShellScript

This following AppleScript code adds your (code which needs to be on your clipboard)

/usr/bin/sdiff <(echo ‘oneThing’) <(echo ‘anotherThing’)

do shell script "echo \"\" >> " & "~/Desktop/test.sh" & " ;pbpaste >> " & "~/Desktop/test.sh"

to that new .sh file which was created.

Then this following AppleScript code is what you were originally trying to achieve lol.

try
	set theResults to (do shell script "~/Desktop/test.sh")
on error errMsg
	set theResults to errMsg
end try