1

I try to use gap version 4.10 with xargs as following:

$ echo 1 | xargs -I '{}' gap -b <( echo 'Display("{}");' ) <( echo 'QUIT;')

which returns

{}

However, it should be

1

Following works

$ gap -b <( echo 'Display("123");' ) <( echo 'QUIT;')
123

If you do not have gap v4.10, you can replace gap with cat and still see my problem:

$ echo 1 | xargs -I '{}' cat <( echo 'Display("{}");' ) <( echo 'QUIT;')
Display("{}");
QUIT;

How can I achieve that the return value becomes?

Display("1");
QUIT;

From my point of view, this has nothing to do with gap but the combination of xargs and process substitution in the shell. I have zsh 5.7.1 and GNU bash 5.0.3 available. xargs is GNU version 4.8.0.

Notes:

  • My motivation is that I want to run a gap script in parallel with different parameters from the shell.
  • gap version 4.10 has not yet the option -c <expr> (commit) which would allow me to avoid using process substitution. However, on the compute server, there is only gap version 4.10.0.
Hotschke
  • 9,402
  • 6
  • 46
  • 53

2 Answers2

2

The process substitutions themselves resolved to file names, not output of the commands inside the substation:

$ echo <(echo foo)
/dev/fd/63

As a result, xargs never sees the {}. It reads 1 from its standard input, but none of the arguments to xargs contain a {}, so no substitution occurs. What you are left with is a single call to gap like

gap -b /dev/fd/63 /dev/fd/62  # The exact paths may differ

and gap, AFAICT, just reads commands from those files and executes them.

If you want to execute the command Display("1"), you need to construct that first, then execute the result. Something like

 # Adjust gap as needed to read from standard input.
echo 1 | xargs -I '{}' echo 'Display("{}"); Quit;' | gap
chepner
  • 497,756
  • 71
  • 530
  • 681
1

As @chepner has pointed out, process substitution is performed by the shell before xargs does its {} substitution and so xargs never sees {}.

Creating a shell command as following solved it for me:

echo 1 | xargs -I '{}' zsh -c "gap -b <( echo 'Display(\"{}\");' ) <( echo 'QUIT;')"
Hotschke
  • 9,402
  • 6
  • 46
  • 53
  • 1
    Just in case, https://carpentries-incubator.github.io/gap-lesson/discuss/ has another scenario, when there is a shell script calling GAP (scroll to "Tips and tricks"). On the server, can you install your own GAP? The GAP 4.10.0 version is dated November 2018, more than 2 years old. – Olexandr Konovalov May 14 '21 at 07:56
  • Thanks for sharing the link which is also helpful. Actually one could add this as another answer to this question. Regarding the gap version: I tried to install my own gap (version 4.11.1) on the server with linuxbrew. Compilation worked but when I invoke `$ ~/.linuxbrew/bin/gap`, I get the error `Illegal instruction`. I am not sure where to start looking for the reason here. Illegal instruction is not a very specific message. – Hotschke May 15 '21 at 07:27
  • Never used linuxbrew - do you mean that you can use https://github.com/gap-system/homebrew-gap with linuxbrew to install on Linux - nice if so! If it does not work, try installing from source as https://www.gap-system.org/Releases/4.11.1.html explains. If that does not work, better to get help by email to [GAP Support](https://www.gap-system.org/Contacts/People/supportgroup.html) (I will see it there anyway). – Olexandr Konovalov May 15 '21 at 19:08
  • P.S. I think the recipe from the GAP Carpentries-style lesson is the same as https://stackoverflow.com/questions/13418849/how-can-i-call-gap-functions-from-a-shell-script – Olexandr Konovalov May 16 '21 at 12:48
  • Hihihihi. I noticed this yesterday evening as well. In my defence it was a long time ago and it got lost in my memory. – Hotschke May 16 '21 at 13:29