Does ar
support input pipe?
No. It appears ar
needs its input to be seekable, it cannot read from a fifo. At least in my Debian 9.
First of all the tool does not recognize -
as stdin. This command
ar -xv -
returns ar: -: No such file or directory
. Omitting the operand doesn't make the tool use its stdin either.
There is a trick to force any tool (that expects a file) to use its stdin: /proc/self/fd/0
(other possibilities: /dev/fd/0
, /dev/stdin
). E.g. you can save an output stream from whatever
as a sparse file, even if whatever
knows nothing about sparse files; you use cp
despite it doesn't normally read its stdin:
whatever | cp --sparse=always /proc/self/fd/0 output_file
You can try this trick with ar
:
curl http://example.com/path/to/package.deb | ar -xv /proc/self/fd/0
but you will get ar: /proc/self/fd/0: Illegal seek
. In my Debian strace
revealed the tool uses lseek(2)
with a negative offset. This fails for a pipe.
With my limited knowledge I found no apparent reason (here) to seek necessarily. Even if in theory one can parse an ar archive without seeking and going back, apparently in practice ar
does seek.
Process substitution also creates an unseekable fifo. This will fail in the same way:
ar -xv <(curl http://example.com/path/to/package.deb)
I think there is no other way than to create a (temporary) seekable file first. In general you can do this explicitly:
tmpf="$(mktemp)" && {
curl http://example.com/path/to/package.deb > "$tmpf" && ar -xv -- "$tmpf"
rm -- "$tmpf"
}
In zsh
there is another form of process substitution that creates and manages a temporary file implicitly:
# in zsh
ar -xv =(curl http://example.com/path/to/package.deb)
This one will work.
Thanks a lot for the detailed answer! I'm currently working in
zsh
and I had not know about=(...)
process substitution! – Yusuf Gören – 2019-09-09T20:15:36.067