zsh and parallel: How to use functions. It says command not found

Viewed 1553

I have a script file

filename: test_sem_zsh.sh

main() {
    echo "Happy day"
}
export -f main 
sem --id testing --fg main

I am trying to run it using zsh

$ zsh test_sem_zsh.sh 
test_sem_zsh.sh:export:4: invalid option(s)
zsh:1: command not found: main

It says two error's 1) main command not found and 2) export:4: invalid option(s)

Where as when i try with bash it works

$ sh test_sem_zsh.sh 
Happy day

So how to get this script working with zsh also

3 Answers

Here is a solution if you want to use parallel, not env_parallel:

function say_hi() { echo -n 'hi '; echo $1 }

F=$(functions say_hi); seq 10 | parallel zsh -c "$F; say_hi $1"

The F=$(functions say_hi) makes an executable string that can import the function into the guest zsh environment, via $F.

Then the actual command say_hi is run with an argument $1, that is passed by parallel into the guest.

An alternative is to bring it in using -I{} like so:

... | parallel -I{} zsh -c "eval $F; say_hi {}"

Not certain what you are trying to do, but this may help you define a chunk of code you can run under sem without needing bash's export:

#!/bin/zsh

# Create script in /tmp
script="/tmp/tmp-$$"
cat <<EOF > "$script"
echo "Happy day"
date
EOF

sem --id testing --fg /bin/zsh "$script"

rm "$script"

This answer is conceptual... for production use, you should set up a trap to remove the script, probably use mktemp and improve security.

sem is just a shorthand for parallel --semaphore.

You can use env_parallel:

#!/usr/bin/zsh

# activate env_parallel (if not already done)
. =env_parallel.zsh

env_parallel --semaphore --id testing --fg main

Or if your environment is too big:

#!/usr/bin/zsh

# activate env_parallel (if not already done)
. =env_parallel.zsh

env_parallel --session

main() {
    echo "Happy day"
}
env_parallel --semaphore --id testing --fg main

env_parallel --end-session
Related