1

While extracting a deb file, the simple curl pipe to ar is not working. I tried

curl http://example.com/path/to/package.deb | ar -xv -

and

curl http://example.com/path/to/package.deb | ar -xv

Looking at man 1 ar, I couldn't find any pointers to pipe usage. Does ar support input pipe?

Thanks!

1 Answer 1

3

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.

2
  • Thanks a lot for the detailed answer! I'm currently working in zsh and I had not know about =(...) process substitution! Commented Sep 9, 2019 at 20:15
  • The cp --sparse=always /proc/self/fd/0 trick is awesome! Thank you so much Commented Aug 26, 2022 at 0:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .