2

If I do this:

echo <(cat)

I get:

/dev/fd/63

so say at the command line I have:

myapp -f <(cat)

when I run it I get this error:

You need to pass a file after the -f flag. The resolved file path was: '/dev/fd/63'. This path did not appear to exist on the filesystem.

How can I determine if the result of the process substitution is an actual file (for validation purposes)? Here is my bash code which generated the error:

  if [[ -L "$file_path" ]]; then
     file_path="$(readlink "$file_path")";
  fi

  if [[ ! -f "$file_path" ]]; then
    echo "You need to pass a file after the -f flag. The resolved file path was: '$file_path'. This path did not appear to exist on the filesystem".;
    return 1;
  fi

if I get rid of my validation, code, I get this:

Could not open the following file for reading: /dev/fd/63 EBADF: bad file descriptor, open '/dev/fd/63'

The node.js code I am using to read from the path is:

const fd = fs.openSync(file_path, 'r');
fs.read(fd, ...);
  • 2
    [ -f file ] tests if file is a regular file, and the file created by a process substitution is a pipe, not a regular file. Also, on Linux, the target of a /dev/fd/n -> /proc/self/fd/n "symlink" is some informative string like type:[inum], not a path for pipes, sockets, etc. – mosvy Aug 3 '19 at 19:50
  • so much for everything is a file lulz..anyway I just want to be able to read from /dev/fd/x, is there some way to do that? – Alexander Mills Aug 3 '19 at 20:22
  • 1
    maybe you should post a complete example; node -e 'fs=require("fs"); fs.openSync(process.argv[1], "r")' <(cat /dev/null) works for me. – mosvy Aug 3 '19 at 20:40
  • 1
    But simply cat <(cat) will not work from console, because the cat inside the process substitution may run in a different process group than the foreground one, and cannot read from the tty. – mosvy Aug 3 '19 at 20:44
  • 1
    I don't have a MacOS system. But someone else may have, so post a complete reproducible testcase. FWIW, on BSD, /dev/fd/N are character special files (they aren't regular files, either). And on FreeBSD you should mount fdescfs if you want to access filedescs > 2 via /dev/fd/N. – mosvy Aug 3 '19 at 20:51
4

To determine, in Bash, whether a string value is a path on your current system, use [[ -e "$path" ]]. This checks whether the path exists, and doesn't make any assumptions about the type of file it points to.

|improve this answer|||||

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.