m4rc3l05
m4rc3l05•3w ago

How to check if stdin is a file?

Hey, how does one check if stdin is a file? in nodejs we could do something like fs.fstatSync(process.stdin.fd).isFile() (example: https://github.com/pinojs/pino-pretty/blob/master/bin.js#L86) which in deno can be translated to Deno.fstatSync(Deno.stdin.rid).isFile. Despite this working for for deno v1, it will not work for deno v2 since both fstatSync and rid will be deprecated, with the first one being deleted entirely. So for deno v2 how can we do this?
13 Replies
Doctor 🤖
Doctor 🤖•3w ago
Assuming the entire stdin is the file path:
const path = (await Array.fromAsync(Deno.stdin.readable.pipeThrough(new TextDecoderStream()))).join('')

console.log((await Deno.stat(path)).isFile)

console.log(Deno.statSync(path).isFile)
const path = (await Array.fromAsync(Deno.stdin.readable.pipeThrough(new TextDecoderStream()))).join('')

console.log((await Deno.stat(path)).isFile)

console.log(Deno.statSync(path).isFile)
jeff.hykin
jeff.hykin•3w ago
I was going to mention Deno.isatty but its also deprecated and there's nothing about it on the migration page. I'm pretty sure I saw the new tty interface somewhere (it might be on the file class now)
m4rc3l05
m4rc3l05•3w ago
Hey, thx for the response, just tried but it only works if the contents of stdin is a filepath and it will not work for example if i execute the ts file like ./foo.js < deno.json for example.
Mrcool 🇵🇸
stdin.isTerminal()
Mrcool 🇵🇸
It's rendered badly in the docs
No description
m4rc3l05
m4rc3l05•3w ago
stdin.isTerminal() does not seem to be what i want, given the example from pino-pretty https://github.com/pinojs/pino-pretty/blob/master/bin.js#L86, they check if stdin is terminal and if stdin is a file and if both are false it means that we are piping to the script and we should do nothing on the first sigint and exit on the next one, allowing to wait for the process being piped to close before closing it self, as explained in https://github.com/pinojs/pino/pull/358#issuecomment-366185875 the stdin.isTerminal() answares the 2 point, but the 1 remain still remains, how do we check it in deno v2 without using deprecated methos? currently i am doing !Deno.stdin.isTerminal() && !Deno.fstatSync(Deno.stdin.rid).isFile bu this will not work for v2 right?
Doctor 🤖
Doctor 🤖•3w ago
Idk if you will be able to still determine if the contents being pipped in is a file or not I think you'll need to end up changing how your cli intends to work
m4rc3l05
m4rc3l05•3w ago
The idea would be to have what pino-pretty does but with deno apis, but then i noticed this issue with the deprecations and started to wonder how would i do it without nodejs apis for deno v2. So currently not possible then? Decided to use nodejs apis for this. thx everybody for you suggestions.
jeff.hykin
jeff.hykin•3w ago
I am interested to know, what is the pipe if not a file?
Doctor 🤖
Doctor 🤖•3w ago
You can pipe any stdout from one command to another. It doesn't necessarily have to be from a file on disk.
jeff.hykin
jeff.hykin•3w ago
At least on Linux and macos those are still files on disk Like they've got a full path, something like /var/p/$pid/1 or /dev/something/$pid/1 and deno .isFile() returns true for those paths There's files that are fifo streams and I think deno has a check somewhere for that since those can exist as a local file too (like $HOME/my_fifo) Ah, here's the check. Only works on MacOS/Linux https://docs.deno.com/api/deno/~/Deno.FileInfo.isFifo
m4rc3l05
m4rc3l05•3w ago
using this simple deno script that uses the deprecated methods/properties:
#!/usr/bin/env deno

console.log("isFile => ", Deno.fstatSync(Deno.stdin.rid).isFile);
#!/usr/bin/env deno

console.log("isFile => ", Deno.fstatSync(Deno.stdin.rid).isFile);
Here what i have:
./foo.ts
isFile => false
./foo.ts
isFile => false
echo "foo" | ./foo.ts
isFile => false
echo "foo" | ./foo.ts
isFile => false
./foo.ts < deno.json
isFile => true
./foo.ts < deno.json
isFile => true
it is only a file if you do input redirection < deno.json
jeff.hykin
jeff.hykin•3w ago
That looks theyre doing a isFile && !isFifo check under the hood to me