vint (vim lint) 的解决方法不允许来自标准输入的输入
Workaround for vint (vim lint) not allowing input from stdin
我有一个不接受标准输入的程序,我必须将我的文件作为标准输入传递。
我试图编写一个包装器,但由于某种原因,过程替换不起作用:
#!/bin/bash
vint "$@" <(cat /dev/stdin)
产量:
ERROR: no such file or directory: `/dev/fd/63`
ls -ld /dev/fd
的输出:
> dr-xr-xr-x 1 root wheel 0 Nov 29 10:57 /dev/fd/
重现步骤:
- 创建一个 vim 文件:
cat <<EOF > myvim.vim
set nocompatible
EOF
- 安装vint
- 创建包装器脚本(如上所述)
- 运行这个:
cat myvim.vim | vint-wrapper
我怎样才能实现这个解决方法?
简短的回答:解决问题
vint
不接受任何类型的套接字或 FIFO:它只允许常规文件作为输入。因此,您需要在 运行 之前将标准输入转储到常规文件中:
#!/usr/bin/env bash
tempfile=$(mktemp "${TMPDIR:-/tmp}/vint.XXXXXX") || exit
trap 'rm -f "$tempfile"' EXIT
cat >"$tempfile" || exit
vint "$tempfile"
...或者,如果您愿意依赖未记录的实施细节,请使用 heredoc 或 herestring 使 shell 代表您进行临时文件管理,同时使用 -
作为输入文件名(vint
明确豁免):
#!/usr/bin/env bash
vint - <<<"$(cat)"
较长的答案:为什么会这样
发生错误是因为 vint
明确检查给定的文件名 是否是一个文件 ,并拒绝其他任何内容:
if not self._should_read_from_stdin(env):
for path_to_lint in paths_to_lint:
if not path_to_lint.exists() or not path_to_lint.is_file():
logging.error('no such file or directory: `{path}`'.format(
path=str(path_to_lint)))
parser.exit(status=1)
...但是,看到 _should_read_from_stdin
了吗?这很重要; vint 可以 从 stdin 读取,但必须给出 -
作为要使用的文件名。
cat myvim.vim | vint -
然而,即便如此,vint
要求给定的文件是可搜索的,而 FIFO 和管道则不是。因此,这将导致:
io.UnsupportedOperation: underlying stream is not seekable
...因为vint
检查文件是否有BOM表示是否有多字节字符的方式涉及读取开头然后倒带;管道不能倒带,但只能从前到后读取一次。
我有一个不接受标准输入的程序,我必须将我的文件作为标准输入传递。 我试图编写一个包装器,但由于某种原因,过程替换不起作用:
#!/bin/bash
vint "$@" <(cat /dev/stdin)
产量:
ERROR: no such file or directory: `/dev/fd/63`
ls -ld /dev/fd
的输出:
> dr-xr-xr-x 1 root wheel 0 Nov 29 10:57 /dev/fd/
重现步骤:
- 创建一个 vim 文件:
cat <<EOF > myvim.vim
set nocompatible
EOF
- 安装vint
- 创建包装器脚本(如上所述)
- 运行这个:
cat myvim.vim | vint-wrapper
我怎样才能实现这个解决方法?
简短的回答:解决问题
vint
不接受任何类型的套接字或 FIFO:它只允许常规文件作为输入。因此,您需要在 运行 之前将标准输入转储到常规文件中:
#!/usr/bin/env bash
tempfile=$(mktemp "${TMPDIR:-/tmp}/vint.XXXXXX") || exit
trap 'rm -f "$tempfile"' EXIT
cat >"$tempfile" || exit
vint "$tempfile"
...或者,如果您愿意依赖未记录的实施细节,请使用 heredoc 或 herestring 使 shell 代表您进行临时文件管理,同时使用 -
作为输入文件名(vint
明确豁免):
#!/usr/bin/env bash
vint - <<<"$(cat)"
较长的答案:为什么会这样
发生错误是因为 vint
明确检查给定的文件名 是否是一个文件 ,并拒绝其他任何内容:
if not self._should_read_from_stdin(env):
for path_to_lint in paths_to_lint:
if not path_to_lint.exists() or not path_to_lint.is_file():
logging.error('no such file or directory: `{path}`'.format(
path=str(path_to_lint)))
parser.exit(status=1)
...但是,看到 _should_read_from_stdin
了吗?这很重要; vint 可以 从 stdin 读取,但必须给出 -
作为要使用的文件名。
cat myvim.vim | vint -
然而,即便如此,vint
要求给定的文件是可搜索的,而 FIFO 和管道则不是。因此,这将导致:
io.UnsupportedOperation: underlying stream is not seekable
...因为vint
检查文件是否有BOM表示是否有多字节字符的方式涉及读取开头然后倒带;管道不能倒带,但只能从前到后读取一次。