Reputation: 5139
I have a program that doesn't accept stdin and I must pass my file as stdin. I tried to write a wrapper but for some reason process-substitution does not work:
#!/bin/bash
vint "$@" <(cat /dev/stdin)
Yields:
ERROR: no such file or directory: `/dev/fd/63`
Output of ls -ld /dev/fd
:
> dr-xr-xr-x 1 root wheel 0 Nov 29 10:57 /dev/fd/
Steps to reproduce:
cat <<EOF > myvim.vim
set nocompatible
EOF
cat myvim.vim | vint-wrapper
How can I achieve this workaround?
Upvotes: 1
Views: 189
Reputation: 295403
vint
doesn't accept any kind of socket or FIFO: It only allows regular files as input. Thus, you'll need to dump stdin into a regular file before running it:
#!/usr/bin/env bash
tempfile=$(mktemp "${TMPDIR:-/tmp}/vint.XXXXXX") || exit
trap 'rm -f "$tempfile"' EXIT
cat >"$tempfile" || exit
vint "$tempfile"
...or, if you're willing to rely on undocumented implementation details, use a heredoc or herestring to make the shell do the temporary-file-management on your behalf, while using -
as the input filename (which vint
explicitly exempts):
#!/usr/bin/env bash
vint - <<<"$(cat)"
The error takes place because vint
explicitly checks whether a filename it is given is a file, and rejects anything else:
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)
...however, see that _should_read_from_stdin
? That's important; vint can read from stdin, but it must be given -
as the filename to use.
cat myvim.vim | vint -
However, even then, vint
requires that file given be seekable, which FIFOs and pipelines are not. Thus, this will result in:
io.UnsupportedOperation: underlying stream is not seekable
...because the way vint
checks whether a file has a BOM indicating whether it has multi-byte characters involves reading the beginning and then rewinding; pipelines cannot be rewound, but can only be read once, front-to-back.
Upvotes: 2