2

I have this command, which works fine for bash:

sh <(curl -sSl https://appi.sh/launch) (launches this interactive script)

I'd like to get this 1-liner working for ksh, too. Currently, it errors with:

syntax error: `(' unexpected` 

Running the script from ksh as sh launch.sh works fine, so I'm hoping there's a way to have a singular 1-liner that will work in both bash/ksh without exponentially increasing the length of the command.

2
  • 1
    Your bourne shell sh is most likely symlinked to bash in which process substitution is supported. Most likely the ksh version you have might not be supporting the process substitution Commented Jun 17, 2020 at 18:02
  • Yes, for most cases, bash will linked to sh. My main workstation is OpenBSD without bash installed, so was a specific ksh, I should have specified my sh shell, as per comment to the accepted answer. Commented Jun 18, 2020 at 13:13

1 Answer 1

4

The process substitution feature comes from ksh, from ksh86 initially, but initially, it was only available on systems that had support for /dev/fd/n special files..

That only changed in ksh93u+ released in 2012, where, like with many of the other shells that later added support for process substitution, ksh could resort to named pipe when /dev/fd was not available. ksh93 is often considered experimental and it not fully backward compatible with ksh88, so you'll find that several systems have stuck to ksh88 anyway which never used named pipe as far as I know.

Process substitution was never added to the public domain clone of ksh (pdksh) nor any of its descendants (like mksh or the sh of OpenBSD), though those give a differently worded error message in that case.

So it looks like you have an older version of AT&T ksh and are on a system where /dev/fd is not available, or was not available when ksh was built.

In any case, process substitution is not a POSIX feature. It's only available in AT&T ksh (since 1986), zsh (since 1990) and bash (since 1993), while yash uses <(cmd) and >(cmd) for something else (process redirection). rc and descendants (and to some extent fish) also have the feature but with different syntax.

Here you could just do:

# without arguments for the script: curl -sSl https://appi.sh/launch | sh # with arguments curl -sSl https://appi.sh/launch | sh -s arg1 arg2 

Though it wouldn't be appropriate for that very launch script as it is reading from its stdin. Or:

# without arguments for the script: sh -c "$(curl -sSl https://appi.sh/launch)" # with arguments: sh -c "$(curl -sSl https://appi.sh/launch)" sh arg1 arg2 

For the whole contents of the script to be passed inline. That would work as long as the script is not too big (fits in the limit of the size of arguments+environment, or the limit on the size of a single argument for those systems that have one like Linux).

In any case, while that script looks like it's written in valid POSIX sh syntax itself, it assumes the system's utilities are GNU-like (see the non-POSIX grep -R or sed -i), so I'd say it's likely not to work on a system that comes with an old version of AT&T ksh.

4
  • Many thanks! The ksh version I was running was from OpenBSD -current of @(#)PD KSH v5.2.14 99/07/13.2which gave that error. For echo ${.sh.version} I do get ksh: ${.sh.version}: bad substitution. I'll switch to the sh -c version you provided, it's still nice and succinct and running with arguments will be a nice improvement for some of my use cases! Commented Jun 18, 2020 at 13:09
  • Also, I will do some testing on Mac soon and likely need to change the sed commands, when gnu-sed can't be relied upon. curl also not being available ubiquitously is another challenge :) Commented Jun 18, 2020 at 13:11
  • 2
    lynx -source, perl libwww's GET, lftp, w3m -dump_source, elinks -source are other options to do HTTP downloads some of which may be more portable than wget/curl on older/non-GNU systems. In any case blindly executing code downloaded off the internet is not something I would advocate personally. Commented Jun 18, 2020 at 13:28
  • Agree. I included the risk in the FAQ and could recommend people download the script and run locally to be more sure. The aim is to not need another closed SaaS to do things most systems are capable of. Hopefully, by showing what it can do, people may just write their own scripts/use the pieces they need. Static website conversion was first case, as I do a few other tools for that already, but hopefully there will be other useful utilities to showcase. Commented Jun 18, 2020 at 16:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.