5

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

oguz ismail
  • 1
  • 16
  • 47
  • 69
Santhosh
  • 9,965
  • 20
  • 103
  • 243
  • 1
    There is no direct way to `export` function in `zsh`. See this cross-site post on Unix Stack Exchange [what is the zsh equivalent of bash's export -f](https://unix.stackexchange.com/q/59360/112235) – Inian May 22 '20 at 05:55
  • I am running my script as `zsh script.sh`. So is it possible to shift to `bash` for this particular command – Santhosh May 22 '20 at 08:16

3 Answers3

1

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 {}"
William Entriken
  • 37,208
  • 23
  • 149
  • 195
0

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.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 1
    Why the tempfile? Couldn't you read the here-doc into a variable and pass that to to `sem`? Also, there might be some bugs: I think this is missing a `chmod u+x tempfile`. When writing an actual script into the heredoc, variables might not behave as expected as they are expanded before running the script. Consider using a literal heredoc `<<'EOF'`. – Socowi May 22 '20 at 15:00
  • @Socowi I agree it's not perfect. No `chmod` is necessary as it is executed with `/bin/zsh` rather than via shebang. Agreed OP may want to use a literal heredoc but his example didn't require that. Thank you for sharing your thoughts. – Mark Setchell May 22 '20 at 15:47
  • Oh right, I missed that `/bin/zsh`. Thank you too for posting this answer and being open :) – Socowi May 22 '20 at 20:31
  • Since there is not way to use `zsh` just like `bash` i am currently using `bash` – Santhosh Jun 01 '20 at 05:31
0

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
Ole Tange
  • 31,768
  • 5
  • 86
  • 104