Shell script not working

I was trying to run a shell script to format my texts. But it didn’t work as expected. The example is as below:

# popclip Pangu 
name: Pangu
title: CJK Formatting
icon: square CJK
applescript: do shell script "pangu '{popclip text}' | pbcopy"
after: paste

The command pangu '{popclip text}' is based on pangu.py. But after installing it and running, nothing happened and the clipboard was empty.

I also tried another command line utility called Autocorrect. It remained the same issue:

# popclip AutoCorrect 
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: do shell script "echo '{popclip full text}' | autocorrect --stdin | pbcopy"
after: paste

Could you please help me? Thanks in advance.

do shell script needs the whole path, not just “pangu”. Run which pangu in Terminal.app to get the path.

Same with “autocorrect”.

1 Like

Thanks for your reply. I’ve changed the command as the full path. Unfortunately, it didn’t still work as expected.

Take Autocorrect as an example:

# popclip AutoCorrect 
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: do shell script "echo '{popclip full text}' | /opt/homebrew/bin/autocorrect --stdin | pbcopy"
after: paste

After the text hello世界 was selected with the command, the result pasted back was hello ‰∏ñÁïå. However, the expected text should be hello 世界.

And what’s worse was that no text was returned with the command of pangu. What’s wrong with this issue?

Do you get the expected result when you run the script in Terminal.app?

Not sure whether that works but you could try to add export LANG="en_US.UTF-8" && to the beginning of the script. If it doesn’t work you need to try another language. Unfortunately I can’t test this.

Yes, the command worked well in Terminal. It seems export LANG="en_US.UTF-8" && did’t work. But thank you so much anyway.

Run locale in Terminal and try to use the result’s first line as language in the script.

Great! It works perfectly! For people who encountered the same issue, the complete example is as below:

# popclip AutoCorrect
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin | pbcopy"
after: paste

Thank you, Pete!

1 Like

By the way, PopClip adds an extra line after pasting, For example, the original text is

hello世界

But the text after processing would be:

hello 世界

Is it possible to disable the extra empty line?

No idea how to do directly it in a shell script, but as you’re using AppleScript (to call the shell script) this should work:

set the clipboard to (text 1 thru -2 in (do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin"))

Works great! You are a genius, Pete! Huge thanks :partying_face:

1 Like

Generally, the script works well, but it has an issue if there isn’t an empty line after the line of the selected texts, the final character will be stripped. I.e., Hello世界 would be Hello 世.

I am not familiar with AppleScript. Could you please help explain what text 1 thru -2 means here. It seems text 1 thru -1 works as expected.

text 1 thru -2 is the whole text except the last character.

If the output varies (i.e. sometimes contains a trailing new line and sometimes doesn’t) then you need to use a conditional that checks whether it’s necessary to strip the last character

set theOutput to (do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin"))
if (character -1 of theOutput is in {linefeed, return}) then set theOutput to (text 1 thru -2 in theOutput)
set the clipboard to theOutput
1 Like

Does the script be like:

# popclip AutoCorrect
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: |
  set theOutput to (do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin"))
  if (character -1 of theOutput is in {linefeed, return}) then set theOutput to (text 1 thru -2 in theOutput)
  set the clipboard to theOutput
after: paste

But it didn’t work after the installation.

No, you’ve got a | at the beginning. Try this

# popclip AutoCorrect
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: set theOutput to (do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin"))
  if (character -1 of theOutput is in {linefeed, return}) then set theOutput to (text 1 thru -2 in theOutput)
  set the clipboard to theOutput
after: paste

I won’t add to the discussion specifics (thanks @Pete) but just to say if you are doing shell scripting for anything more complicated than a very simple comand, I would recommend doing it with a “traditional” extension inside a popclipext directory, with an actual shell script file. This way, you don’t have to worry about escaping your shell script inside an applescript inside a YAML file.

Also if you do it that way, in general you don’t need to pbcopy at the end of a script then paste. You can return the result as stdout from the script then paste-result directly instead.

Here’s an example of a simple plain shell script extension: PopClip-Extensions/source-contrib/MD5.popclipext at master · pilotmoon/PopClip-Extensions · GitHub

One other thing, echo adds a newline by defualt unless you add the -n flag to suppress newline.

1 Like

Thank you, @Pete, @nick

I’ve tried to add the -n flag, but it didn’t work, the trailing newline was still reserved:

# popclip AutoCorrect
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: do shell script "export LANG='en_US.UTF-8' && echo -n '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin | pbcopy"
after: paste

The extension with an actual shell script file is a good way, but the config file (JSON, YAML, plist) is hard to write I thought.

So this …

doesn’t work?

Yes, it doesn’t work.

In my case, paste-result is better, and no need to process the trailing newline:

# popclip AutoCorrect
name: AutoCorrect
title: CJK Formatting
icon: square CJK
applescript: do shell script "export LANG='en_US.UTF-8' && echo '{popclip text}' | /opt/homebrew/bin/autocorrect --stdin"
after: paste-result

I’ve created a GitHub repository to share the PopClip extension we discussed here. Thanks again! @Pete @nick

1 Like