我有这个命令,它适用于bash
:
sh <(curl -sSl https://appi.sh/launch)
(推出这个交互式脚本)
我也想让这个 1-liner 为 工作ksh
。目前,它的错误如下:
syntax error: `(' unexpected`
ksh
从as运行脚本sh launch.sh
效果很好,所以我希望有一种方法可以让单个 1-liner 可以在 bash/ksh 中工作,而不会以指数方式增加命令的长度。
答案1
/dev/fd/n
进程替换功能最初来自 ksh,来自 ksh86,但最初仅在支持特殊文件的系统上可用。
这种情况直到 2012 年发布的 ksh93u+ 才有所改变,与后来增加了对进程替换支持的许多其他 shell 一样,ksh 在/dev/fd
不可用时可以求助于命名管道。ksh93
通常被认为是实验性的而且它并不完全向后兼容 ksh88,所以你会发现有几个系统坚持使用 ksh88,据我所知,它们从未使用过命名管道。
进程替换从未添加到 ksh (pdksh) 及其任何后代(如 mksh 或 OpenBSD 的 sh)的公共域克隆中,尽管在这种情况下它们会给出不同措辞的错误消息。
因此,您似乎拥有旧版本的 AT&T ksh,并且所在的系统/dev/fd
不可用,或者在构建 ksh 时不可用。
无论如何,进程替换不是 POSIX 功能。它仅在 AT&T ksh(自 1986 年起)、zsh(自 1990 年起)和 bash(自 1993 年起)中可用,而 yash 将<(cmd)
和>(cmd)
用于其他用途(进程重定向)。rc
后代(在某种程度上fish
)也具有该功能,但语法不同。
在这里你可以这样做:
# without arguments for the script:
curl -sSl https://appi.sh/launch | sh
# with arguments
curl -sSl https://appi.sh/launch | sh -s arg1 arg2
尽管它不适合该launch
脚本,因为它是从标准输入读取的。或者:
# 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
用于内联传递脚本的全部内容。只要脚本不太大(适合参数+环境的大小限制,或者对于具有 Linux 等系统的单个参数大小的限制),这种方法就可以工作。
无论如何,同时那个脚本看起来它sh
本身是用有效的 POSIX 语法编写的,它假设系统的实用程序是类似 GNU 的(请参阅非 POSIXgrep -R
或sed -i
),所以我想说它可能无法在带有旧版本 AT&T ksh 的系统上工作。