如何在进程替换中使用case/esac?

How to use case/esac in process substitution?

我有以下行可以正常工作:

while getopts :t t; do case $t in t) echo $t; break; esac; done

然而,当我尝试将其用作命令替换时,bash 失败并出现错误。

代码:

#!/usr/bin/env bash
echo $BASH_VERSION
[ "$(while getopts :t t; do case $t in t) echo $t; break; esac; done)" = "t" ] && echo "Option specified."

结果:

$ ./test.sh -a -b -c -t
4.3.42(1)-release
./test.sh: line 3: unexpected EOF while looking for matching `"'
./test.sh: line 4: syntax error: unexpected end of file

t) 中的反斜杠 \) 没有帮助。 (t) 语法在 GNU bash 3.2.57 中有效,但在 4.3.42 中无效。

使用反引号似乎对两个版本都适用:

[ "`while getopts :t t; do case $t in t) echo $t; break; esac; done`" = "t" ] && echo "Option specified."

但是我不想使用那个语法,因为它是 deprecated

如何在上述命令替换 ($()) 中使用 case 语法?

或者也许有其他方法可以做同样的事情?

主要是检查-t参数是否已经指定给脚本,如果是则执行一些命令。

如果您有一个 bash 版本,其中扫描器被破坏的方式仅在不平衡时终止 ) -- 当前 4.3 中不再存在的错误 --您可以按如下方式解决它:

#!/usr/bin/env bash
[ "$(while getopts :t t; do case $t in (t) echo $t; break;; esac; done)" = "t" ] && echo "Option specified."

这里的主要区别是使用 (t) 而不是 t),从而导致括号平衡。这是 syntax explicitly allowed in the POSIX sh standard.

不过,您想要完成什么? [ ... ] 和命令替换很可能是可以避免的。也许这就是您正在寻找的:

while getopts :t t; do
  case $t in t) true; break;; *) false;; esac
done && echo Yes || echo No

while循环的退出状态就是case语句的退出状态。无需将其包装在 [ 中以检查它是否为真,无论如何这通常是一种反模式。