Skip to main content
added 49 characters in body
Source Link
Kamil Maciorowski
  • 75.7k
  • 22
  • 152
  • 229

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.

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. 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.

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.

Source Link
Kamil Maciorowski
  • 75.7k
  • 22
  • 152
  • 229

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. 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.