Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Thought of an example.

vs

  cp =( ( echo foo; sleep 1; echo bar) | sponge) ) foobar
The first will complete instantly and result in a file named foobar but whose contents is either zero length or foo, depending on how unlucky you are.

The second takes one second to complete and results in a file named foobar containing foobar.

It’s strange that vanilla process substitution can’t seem to solve this at all.



I'm not sure what you're trying to say here.

With GNU cp on Linux, the commands

  cp <( ( echo foo; sleep 1; echo bar) | sponge ) foobar
  cp =( ( echo foo; sleep 1; echo bar) | sponge ) foobar
both have the same result: the file "foobar" containing the string "foo\nbar\n".


I didn't test it. You're right, I'm simply mistaken.

Here's a better (but awkward) illustration of the problem:

  :~$ python3 -c 'import sys; import shutil; shutil.copy(sys.argv[1], "foobar")' <
  (echo foo ; sleep 1 ; echo bar)
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shutil.py", line 427, in copy
      copyfile(src, dst, follow_symlinks=follow_symlinks)
    File "/opt/homebrew/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shutil.py", line 257, in copyfile
      raise SpecialFileError("`%s` is a named pipe" % fn)
  shutil.SpecialFileError: `/dev/fd/11` is a named pipe
  :~$ python3 -c 'import sys; import shutil; shutil.copy(sys.argv[1], "foobar")' =(echo foo ; sleep 1 ; echo bar)
Notice the difference:

  :~$ echo =(echo foo ; sleep 1; echo bar)
  /tmp/zshbusU5D
  :~$ echo <(echo foo ; sleep 1; echo bar)
  /dev/fd/11
/dev/fd/11 is a named pipe, whereas /tmp/zshbEF1D9 is a plain file. There are situations where named pipes fail, where you actually do need a plain file, and I can't think of a single one offhand. :)

"I've run into it in the past" is all I can say. And the above snippet at least gives one specific example of a hypothetical case.


> There are situations where named pipes fail, where you actually do need a plain file, and I can't think of a single one offhand. :)

My go-to use-case for =() is

  okular =(dot -Tpdf foo.dot)
PDF-viewers and its ilk typically don't work on non-files.


> There are situations where named pipes fail, where you actually do need a plain file

In general: If the command you are passing the named pipe to expects a file which it can randomly access, a named pipe won’t work.

I ran into this today using a python tool, yamldiff. I was trying to diff a local yaml file with one from a cluster obtained via kubectl, eg:

yamldiff localManifest.yaml <(kubectl get … —output yaml)

and it failed with python telling me the file wasn’t seekable. Then I remembered this thread which I had initially read a few days ago and tried =() (since I use shell) — and it worked!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: