其他地方描述了此问题的根本原因,并提供了部分解决方案。
例如:stdout不是tty,stdin也不是tty
我在MSYS2或MINGW64环境中遇到问题的命令行示例如下:
# psql -c 'd' | grep public
stdout is not a tty
以下是输出,如果不通过管道发送到grep
:
# psql -c 'd'
List of relations
Schema | Name | Type | Owner
--------+----------------+----------+----------
public | tagname | table | postgres
public | tagname_id_seq | sequence | postgres
(2 rows)
为了重定向stdout,显然有必要编辑命令行,将psql
更改为psql.exe
。这种修改达到了目的:
# psql.exe -c 'd' | grep public
public | tagname | table | postgres
public | tagname_id_seq | sequence | postgres
无论stdout
是否重定向,此版本都有效:
# psql.exe -c 'd'
List of relations
Schema | Name | Type | Owner
--------+----------------+----------+----------
public | tagname | table | postgres
public | tagname_id_seq | sequence | postgres
(2 rows)
请注意,该问题仅存在于某些程序中。例如,/usr/bin/find
与是否指定了.exe
扩展无关。此外,psql.exe
的cygwin
版本不受此限制。
如果您总是可以将psql
调用为psql.exe
,那么附加.exe
的解决方法可以用别名隐藏,但使用扩展调用时交互会话会出现问题。(例如MSYS_NT-10.0-19042
下的ConEmu
终端(
所以我的问题是:有可能创建一个包装程序(例如,在golang
或C
中,或者一个shell脚本(来隐藏这个问题吗?目标是支持可选的可重定向命令行,而不需要.exe
扩展。
假设包装器被命名为";fixtty";,它将生成一个可以重定向也可以不重定向的命令行。换句话说,这两条命令行都不会失败,并显示错误消息:
# fixtty psql -c 'd'
# fixtty psql -c 'd' | grep public
隐藏问题的包装器脚本(称为fixtty
(:
#!/bin/bash
if [ -t 1 ]; then
# stdout is a terminal
"$@"
else
# stdout is a file or pipe
PROG=$1 ; shift
set -- "$PROG.exe" "$@" # append .exe suffix
"$@"
fi
用法:
$ fixtty psql -c 'd' # unfiltered `stdout`
$ fixtty psql -c 'd' | grep public # filtered
$ fixtty psql # launch interactive session