I am using Cygwin - no, don't close yet - and I am having trouble with the <() syntax. A program refuses to accept the file descriptor that I am passing it, but other programs will accept it fine. My hypothesis is that the program is passing the file descriptor to one of its helper programs, which then does not receive the pipe (just the usual 0, 1 and 2, of which 0 and 2 are probably closed). This works fine with cat, just not with this program.


./jpegtran -copy all -drop +16+16 <(echo "JPEG FILE") -outfile out.jpeg out.jpeg

This produces the error message:

C:\path\to\jpegtran.exe: can't open /dev/fd/63 for reading

Is there a way to do this? Or will I have to resort to... temporary files? *shudder*

As far as I know, Cygwin simulates a POSIX environment for all intents and purposes. If it can't create a pseudo-file using named pipes (something I know is possible using the Windows API under //./pipe/pipename, which should be able to be handled using whatever name-rewriting is currently being used for when I pass a Windows program a /cygdrive/c/ path) then I'm happy with answers that will work on an actual 'nix box.

  • 1
    I dont have Cygwin right here. Can you edit the question with the command echo <(echo "JPEG") and the output. That will show the filename. – hschou Nov 13 '17 at 20:34
  • @hschou Cygwin takes ages to start and my computer isn't stable at the moment. It's /proc/63 or something like that - the same as on Debian. – wizzwizz4 Nov 13 '17 at 22:19
  • I'll integrate this information in ~20 hours, but /dev/stdin has the same issue, with an identical error message. – wizzwizz4 Nov 13 '17 at 22:21
  • You have out.jpeg twice in your command...typo presumably...? So what does "refuse to accept" mean? Is there an error message? – B Layer Nov 13 '17 at 22:39
  • The jpegtran manpage (for Cygwin) doesn't indicate that you can pass it all those files. It says "reads the named JPEG/JFIF file, or the standard input if no file is named, and produces a JPEG/JFIF file on the standard output." Source code indicates same: it accepts 0 or 1 filename. Are you using a standard build here? – B Layer Nov 13 '17 at 22:50

Note: After a lot of back and forth it's been determined that OP is using a non-standard version of jpegtran that supports "crop-and-drop" (copy a portion of one image into another image).

So why doesn't process substitution (aka PS) work with this feature? Short of looking at the code we can't say with absolute, 100% confidence but there's a highly likely explanation. PS creates a special file that is effectively a read-only pipe from which the data is accessed in a streaming manner. When using it you cannot, of course, write to the file and, more importantly, you cannot seek in it (random access). Try using PS with any tool you can think of that doesn't use a streaming model (vim is one example). You'll either be restricted in what you can do or it just won't work at all.

Given that for this feature jpegtran is extracting a rectangular subset of the source image (JPEG) it seems highly unlikely that whoever implemented the feature imposed a constraint on themselves that restricted access to one-way streaming. Pulling out a portion of an image is clearly an operation where seek would be very useful if not mandatory. As such, PS is not allowed.

  • I suspect that I read pages about a fork of jpegtran. However, jpegtran didn't complain about the invalid argument -drop and it corrected some of my other syntax (messing up the +X+Y bit) so I think I have the same version of the program that -drop exists in. – wizzwizz4 Nov 15 '17 at 21:07
  • What does your man page say? – B Layer Nov 15 '17 at 21:08
  • BTW, even if you are using a fork there are still potentially critical details in my answer. E.g. the point about <(echo "JPEG FILE") likely acting as an input file since it's not associated with -drop (due to intervening +16+16). Of course, unless you can post some documentation it's all guess work on my part at this point. – B Layer Nov 15 '17 at 21:43
  • I've finally found something mentioning this. stackoverflow.com/a/29615714/5223757 I found this by using searching for the original problem I solved with this parameter. – wizzwizz4 Nov 15 '17 at 21:59
  • I think this man page might be out of date - I have weak recollections of this being on the new features list of the page I downloaded the build I used from. – wizzwizz4 Nov 15 '17 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.