On Linux, one can run readlink /proc/self/fd/0 or readlink /dev/fd/0 to get the name of any file or device attached to stdin.
Is this possible on Mac OS?
To explain the use case -- I have a script which behaves roughly akin to the following:
IFS= read -r -d '' stdin_content ||:
for target; do
ssh "$target" "$command" < <(printf %s "$stdin_content")
done
This has obvious caveats when the content to be read contains literal NUL values (which can't be stored in scalar variables in shell), and with respect to losing position information within the input file; I'm willing to ignore those at the moment, or round-trip the $stdin variable through base64 storage if need be.
It would be helpful if I could detect the case where the script's stdin were coming from a regular file, and directly redirect from that file within the loop. [ -f /dev/fd/0 ] actually does do the right thing in bash on Mac OS, despite /dev/fd/0 not existing (the test builtin is aware of the /dev/fd extension), but I'm at a loss for a means to retrieve its name.
You can use the fcntl function with the (BSD and Mac OS X specific) option F_GETPATH:
$ cat stdinname.c
#include <stdio.h>
#include <fcntl.h>
int main() {
char path[80];
fcntl(0, F_GETPATH, path);
printf("stdin is `%s`\n", path);
}
$ gcc stdinname.c
$ ./a.out < stdinname.c
stdin is `/Users/eduffy/junk/stdinname.c`
The code should include some error checking .. but the gist of it is there.
Edit: Missed the bash part. This seems to work .. not as nice as the /proc/self/... approach:
lsof -p $$ | awk '{if($4=="0r"){print $9}}'
Edit 2: Here's a version that outputs the fields separated by the NULL byte for safer parsing.
lsof -p $$ -F fn0 | awk '-F\0' '{if($1=="f0"){print substr($2,2)}}'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With