How to check if stdin is /dev/null from the shell?











up vote
8
down vote

favorite
3












On Linux, is there a way for a shell script to check if its standard input is redirected from the null device (1, 3) *, ideally without reading anything?



The expected behavior would be:



./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no

EDIT

mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes


I suspect I "just" need to read the maj/min number of the input device. But I can't find a way of doing that from the shell.






*No necessary just /dev/null, but any null device even if manually created with mknod.








share|improve this question




















  • 2




    Do you need to know if it's /dev/null, or just that it's not a tty?
    – roaima
    2 days ago










  • The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
    – Isaac
    2 days ago










  • I need (actually "needed") to know if the standard input was the null device.
    – Sylvain Leroux
    2 days ago






  • 2




    I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
    – Sylvain Leroux
    2 days ago












  • "So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
    – Sylvain Leroux
    2 days ago















up vote
8
down vote

favorite
3












On Linux, is there a way for a shell script to check if its standard input is redirected from the null device (1, 3) *, ideally without reading anything?



The expected behavior would be:



./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no

EDIT

mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes


I suspect I "just" need to read the maj/min number of the input device. But I can't find a way of doing that from the shell.






*No necessary just /dev/null, but any null device even if manually created with mknod.








share|improve this question




















  • 2




    Do you need to know if it's /dev/null, or just that it's not a tty?
    – roaima
    2 days ago










  • The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
    – Isaac
    2 days ago










  • I need (actually "needed") to know if the standard input was the null device.
    – Sylvain Leroux
    2 days ago






  • 2




    I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
    – Sylvain Leroux
    2 days ago












  • "So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
    – Sylvain Leroux
    2 days ago













up vote
8
down vote

favorite
3









up vote
8
down vote

favorite
3






3





On Linux, is there a way for a shell script to check if its standard input is redirected from the null device (1, 3) *, ideally without reading anything?



The expected behavior would be:



./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no

EDIT

mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes


I suspect I "just" need to read the maj/min number of the input device. But I can't find a way of doing that from the shell.






*No necessary just /dev/null, but any null device even if manually created with mknod.








share|improve this question















On Linux, is there a way for a shell script to check if its standard input is redirected from the null device (1, 3) *, ideally without reading anything?



The expected behavior would be:



./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no

EDIT

mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes


I suspect I "just" need to read the maj/min number of the input device. But I can't find a way of doing that from the shell.






*No necessary just /dev/null, but any null device even if manually created with mknod.





linux shell devices stdin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago

























asked 2 days ago









Sylvain Leroux

417210




417210








  • 2




    Do you need to know if it's /dev/null, or just that it's not a tty?
    – roaima
    2 days ago










  • The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
    – Isaac
    2 days ago










  • I need (actually "needed") to know if the standard input was the null device.
    – Sylvain Leroux
    2 days ago






  • 2




    I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
    – Sylvain Leroux
    2 days ago












  • "So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
    – Sylvain Leroux
    2 days ago














  • 2




    Do you need to know if it's /dev/null, or just that it's not a tty?
    – roaima
    2 days ago










  • The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
    – Isaac
    2 days ago










  • I need (actually "needed") to know if the standard input was the null device.
    – Sylvain Leroux
    2 days ago






  • 2




    I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
    – Sylvain Leroux
    2 days ago












  • "So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
    – Sylvain Leroux
    2 days ago








2




2




Do you need to know if it's /dev/null, or just that it's not a tty?
– roaima
2 days ago




Do you need to know if it's /dev/null, or just that it's not a tty?
– roaima
2 days ago












The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
– Isaac
2 days ago




The output of { readlink -f /dev/stdin; } <&6 for the case where you used exec and removed the node is /root/secretunknownname (deleted). As it shows that the file got deleted: Isn't that enough for what you need?
– Isaac
2 days ago












I need (actually "needed") to know if the standard input was the null device.
– Sylvain Leroux
2 days ago




I need (actually "needed") to know if the standard input was the null device.
– Sylvain Leroux
2 days ago




2




2




I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
– Sylvain Leroux
2 days ago






I am trying to find my way in a (very poorly designed!) industrial system. And it sometimes maps input of worker utility to the null device, or, some other times, to the actual hardware device. In both cases using the same code, but with different major/minor dev numbers. We are trying to track when (and why!) it sometimes chose to use one or the other. For now, the stat solution is the only one working.
– Sylvain Leroux
2 days ago














"So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
– Sylvain Leroux
2 days ago




"So, the example on your EDIT doesn't really reproduce the problem that you describe, or: does it?" It does. Input in redirected from the null device. Which is usually accessed through /dev/null, but not necessary. You can "alias" is with mknod s illustrated in my example.
– Sylvain Leroux
2 days ago










3 Answers
3






active

oldest

votes

















up vote
18
down vote



accepted










On linux, you can do it with:



stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }


On a linux without stat(1) (eg. the busybox on your router):



stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }


On *bsd:



stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }


On systems like *bsd and solaris, /dev/stdin, /dev/fd/0 and /proc/PID/fd/0 are not "magical" symlinks as on linux, but character devices which will switch to the real file when opened. A stat(2) on their path will return something different than a fstat(2) on the opened file descriptor.



This means that the linux example will not work there, even with GNU coreutils installed. If the versions of GNU stat(1) is recent enough, you can use the - argument to let it do a fstat(2) on the file descriptor 0, just like the stat(1) from *bsd:



stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }


It's also very easy to do the check portably in any language which offers an interface to fstat(2), eg. in perl:



stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }





share|improve this answer



















  • 1




    As the device type of /dev/null is 1:3, you could test for that immediately.
    – RudiC
    2 days ago






  • 12




    FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
    – Sylvain Leroux
    2 days ago








  • 2




    Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
    – user1717828
    2 days ago










  • "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
    – roaima
    yesterday










  • @user1717828 see here and here and here for some clarity.
    – roaima
    yesterday


















up vote
15
down vote













On Linux, to determine whether standard input is redirected from /dev/null, you can check whether /proc/self/fd/0 has the same device and inode as /dev/null:



if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi


You can use /dev/stdin instead of /proc/self/fd/0.



If you want to check whether standard input is redirected from the null device, you need to compare major and minor device numbers, for example using stat (see also mosvy’s answer):



if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi


or, if you don’t care about this being Linux-specific,



if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi





share|improve this answer



















  • 2




    -ef, True if FILE1 and FILE2 refer to the same device and inode
    – Rui F Ribeiro
    2 days ago












  • very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
    – glenn jackman
    2 days ago






  • 1




    The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
    – Stéphane Chazelas
    2 days ago












  • @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
    – Stephen Kitt
    2 days ago










  • Oops, missed that.
    – Stéphane Chazelas
    2 days ago


















up vote
3
down vote













Portably, to check that stdin is the null device (open on /dev/null or not (like a copy of /dev/null)), with zsh (whose stat builtin predates both GNU and FreeBSD stat by the way (not IRIX' though))):



zmodload zsh/stat
if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
echo stdin is open on the null device
fi


(note that it doesn't say if the file descriptor was open in read-only, write-only or read+write mode).



To check that it's open on the current /dev/null file specifically (not /some/chroot/dev/null for instance), on Linux only (where /dev/stdin is implemented as a symlink to the file open on fd 0 instead of a special device which when open acts like a dup(0) in other systems):



if [ /dev/stdin -ef /dev/null ]; then
echo stdin is open on /dev/null
fi


On non-Linux, you can try:



if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
echo stdin is open on /dev/null
fi





share|improve this answer





















    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "106"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f484228%2fhow-to-check-if-stdin-is-dev-null-from-the-shell%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    18
    down vote



    accepted










    On linux, you can do it with:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }


    On a linux without stat(1) (eg. the busybox on your router):



    stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }


    On *bsd:



    stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }


    On systems like *bsd and solaris, /dev/stdin, /dev/fd/0 and /proc/PID/fd/0 are not "magical" symlinks as on linux, but character devices which will switch to the real file when opened. A stat(2) on their path will return something different than a fstat(2) on the opened file descriptor.



    This means that the linux example will not work there, even with GNU coreutils installed. If the versions of GNU stat(1) is recent enough, you can use the - argument to let it do a fstat(2) on the file descriptor 0, just like the stat(1) from *bsd:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }


    It's also very easy to do the check portably in any language which offers an interface to fstat(2), eg. in perl:



    stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }





    share|improve this answer



















    • 1




      As the device type of /dev/null is 1:3, you could test for that immediately.
      – RudiC
      2 days ago






    • 12




      FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
      – Sylvain Leroux
      2 days ago








    • 2




      Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
      – user1717828
      2 days ago










    • "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
      – roaima
      yesterday










    • @user1717828 see here and here and here for some clarity.
      – roaima
      yesterday















    up vote
    18
    down vote



    accepted










    On linux, you can do it with:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }


    On a linux without stat(1) (eg. the busybox on your router):



    stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }


    On *bsd:



    stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }


    On systems like *bsd and solaris, /dev/stdin, /dev/fd/0 and /proc/PID/fd/0 are not "magical" symlinks as on linux, but character devices which will switch to the real file when opened. A stat(2) on their path will return something different than a fstat(2) on the opened file descriptor.



    This means that the linux example will not work there, even with GNU coreutils installed. If the versions of GNU stat(1) is recent enough, you can use the - argument to let it do a fstat(2) on the file descriptor 0, just like the stat(1) from *bsd:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }


    It's also very easy to do the check portably in any language which offers an interface to fstat(2), eg. in perl:



    stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }





    share|improve this answer



















    • 1




      As the device type of /dev/null is 1:3, you could test for that immediately.
      – RudiC
      2 days ago






    • 12




      FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
      – Sylvain Leroux
      2 days ago








    • 2




      Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
      – user1717828
      2 days ago










    • "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
      – roaima
      yesterday










    • @user1717828 see here and here and here for some clarity.
      – roaima
      yesterday













    up vote
    18
    down vote



    accepted







    up vote
    18
    down vote



    accepted






    On linux, you can do it with:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }


    On a linux without stat(1) (eg. the busybox on your router):



    stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }


    On *bsd:



    stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }


    On systems like *bsd and solaris, /dev/stdin, /dev/fd/0 and /proc/PID/fd/0 are not "magical" symlinks as on linux, but character devices which will switch to the real file when opened. A stat(2) on their path will return something different than a fstat(2) on the opened file descriptor.



    This means that the linux example will not work there, even with GNU coreutils installed. If the versions of GNU stat(1) is recent enough, you can use the - argument to let it do a fstat(2) on the file descriptor 0, just like the stat(1) from *bsd:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }


    It's also very easy to do the check portably in any language which offers an interface to fstat(2), eg. in perl:



    stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }





    share|improve this answer














    On linux, you can do it with:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }


    On a linux without stat(1) (eg. the busybox on your router):



    stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }


    On *bsd:



    stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }


    On systems like *bsd and solaris, /dev/stdin, /dev/fd/0 and /proc/PID/fd/0 are not "magical" symlinks as on linux, but character devices which will switch to the real file when opened. A stat(2) on their path will return something different than a fstat(2) on the opened file descriptor.



    This means that the linux example will not work there, even with GNU coreutils installed. If the versions of GNU stat(1) is recent enough, you can use the - argument to let it do a fstat(2) on the file descriptor 0, just like the stat(1) from *bsd:



    stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }


    It's also very easy to do the check portably in any language which offers an interface to fstat(2), eg. in perl:



    stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 days ago

























    answered 2 days ago









    mosvy

    4,831322




    4,831322








    • 1




      As the device type of /dev/null is 1:3, you could test for that immediately.
      – RudiC
      2 days ago






    • 12




      FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
      – Sylvain Leroux
      2 days ago








    • 2




      Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
      – user1717828
      2 days ago










    • "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
      – roaima
      yesterday










    • @user1717828 see here and here and here for some clarity.
      – roaima
      yesterday














    • 1




      As the device type of /dev/null is 1:3, you could test for that immediately.
      – RudiC
      2 days ago






    • 12




      FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
      – Sylvain Leroux
      2 days ago








    • 2




      Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
      – user1717828
      2 days ago










    • "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
      – roaima
      yesterday










    • @user1717828 see here and here and here for some clarity.
      – roaima
      yesterday








    1




    1




    As the device type of /dev/null is 1:3, you could test for that immediately.
    – RudiC
    2 days ago




    As the device type of /dev/null is 1:3, you could test for that immediately.
    – RudiC
    2 days ago




    12




    12




    FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
    – Sylvain Leroux
    2 days ago






    FWIW the question was not about shell syntax. For what is concerning my issue, if the answer had only pointed me to the stat command I would have already been quite satisfied. I don't see the point in starting an editing war between ` and $( supporters. Personally, I prefer $(...) and there are some POSIX rationales in favor of that syntax (pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) But I don't see the point in downvoting an otherwise correct answer for something not related with the question.
    – Sylvain Leroux
    2 days ago






    2




    2




    Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
    – user1717828
    2 days ago




    Could someone explain why $( ... ) is preferred over backticks in the context of this answer?
    – user1717828
    2 days ago












    "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
    – roaima
    yesterday




    "what bug does that fix"? It doesn't fix a bug. The $(..) style nests more easily and AIUI is the POSIX preferred approach. I certainly hadn't intended to start any form of editing war, preferring to comment with a suggestion rather than change your excellent answer.
    – roaima
    yesterday












    @user1717828 see here and here and here for some clarity.
    – roaima
    yesterday




    @user1717828 see here and here and here for some clarity.
    – roaima
    yesterday












    up vote
    15
    down vote













    On Linux, to determine whether standard input is redirected from /dev/null, you can check whether /proc/self/fd/0 has the same device and inode as /dev/null:



    if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi


    You can use /dev/stdin instead of /proc/self/fd/0.



    If you want to check whether standard input is redirected from the null device, you need to compare major and minor device numbers, for example using stat (see also mosvy’s answer):



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi


    or, if you don’t care about this being Linux-specific,



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi





    share|improve this answer



















    • 2




      -ef, True if FILE1 and FILE2 refer to the same device and inode
      – Rui F Ribeiro
      2 days ago












    • very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
      – glenn jackman
      2 days ago






    • 1




      The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
      – Stéphane Chazelas
      2 days ago












    • @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
      – Stephen Kitt
      2 days ago










    • Oops, missed that.
      – Stéphane Chazelas
      2 days ago















    up vote
    15
    down vote













    On Linux, to determine whether standard input is redirected from /dev/null, you can check whether /proc/self/fd/0 has the same device and inode as /dev/null:



    if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi


    You can use /dev/stdin instead of /proc/self/fd/0.



    If you want to check whether standard input is redirected from the null device, you need to compare major and minor device numbers, for example using stat (see also mosvy’s answer):



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi


    or, if you don’t care about this being Linux-specific,



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi





    share|improve this answer



















    • 2




      -ef, True if FILE1 and FILE2 refer to the same device and inode
      – Rui F Ribeiro
      2 days ago












    • very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
      – glenn jackman
      2 days ago






    • 1




      The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
      – Stéphane Chazelas
      2 days ago












    • @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
      – Stephen Kitt
      2 days ago










    • Oops, missed that.
      – Stéphane Chazelas
      2 days ago













    up vote
    15
    down vote










    up vote
    15
    down vote









    On Linux, to determine whether standard input is redirected from /dev/null, you can check whether /proc/self/fd/0 has the same device and inode as /dev/null:



    if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi


    You can use /dev/stdin instead of /proc/self/fd/0.



    If you want to check whether standard input is redirected from the null device, you need to compare major and minor device numbers, for example using stat (see also mosvy’s answer):



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi


    or, if you don’t care about this being Linux-specific,



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi





    share|improve this answer














    On Linux, to determine whether standard input is redirected from /dev/null, you can check whether /proc/self/fd/0 has the same device and inode as /dev/null:



    if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi


    You can use /dev/stdin instead of /proc/self/fd/0.



    If you want to check whether standard input is redirected from the null device, you need to compare major and minor device numbers, for example using stat (see also mosvy’s answer):



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi


    or, if you don’t care about this being Linux-specific,



    if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 days ago

























    answered 2 days ago









    Stephen Kitt

    158k24351425




    158k24351425








    • 2




      -ef, True if FILE1 and FILE2 refer to the same device and inode
      – Rui F Ribeiro
      2 days ago












    • very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
      – glenn jackman
      2 days ago






    • 1




      The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
      – Stéphane Chazelas
      2 days ago












    • @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
      – Stephen Kitt
      2 days ago










    • Oops, missed that.
      – Stéphane Chazelas
      2 days ago














    • 2




      -ef, True if FILE1 and FILE2 refer to the same device and inode
      – Rui F Ribeiro
      2 days ago












    • very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
      – glenn jackman
      2 days ago






    • 1




      The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
      – Stéphane Chazelas
      2 days ago












    • @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
      – Stephen Kitt
      2 days ago










    • Oops, missed that.
      – Stéphane Chazelas
      2 days ago








    2




    2




    -ef, True if FILE1 and FILE2 refer to the same device and inode
    – Rui F Ribeiro
    2 days ago






    -ef, True if FILE1 and FILE2 refer to the same device and inode
    – Rui F Ribeiro
    2 days ago














    very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
    – glenn jackman
    2 days ago




    very cool. bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null' then do that again with </dev/null. +1
    – glenn jackman
    2 days ago




    1




    1




    The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
    – Stéphane Chazelas
    2 days ago






    The /dev/stdin being a symlink to the original file is specific to Linux, so all those solutions are Linux-specific anyway. The stat-based ones require GNU or busybox stat. With recent versions of GNU stat, you can use stat - to do a fstat() on fd 0 which would then work on non-Linux systems.
    – Stéphane Chazelas
    2 days ago














    @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
    – Stephen Kitt
    2 days ago




    @Stéphane the last part is exactly the situation the OP ran into, which is why I wrote up both solutions, distinguishing between /dev/null and the null device.
    – Stephen Kitt
    2 days ago












    Oops, missed that.
    – Stéphane Chazelas
    2 days ago




    Oops, missed that.
    – Stéphane Chazelas
    2 days ago










    up vote
    3
    down vote













    Portably, to check that stdin is the null device (open on /dev/null or not (like a copy of /dev/null)), with zsh (whose stat builtin predates both GNU and FreeBSD stat by the way (not IRIX' though))):



    zmodload zsh/stat
    if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
    echo stdin is open on the null device
    fi


    (note that it doesn't say if the file descriptor was open in read-only, write-only or read+write mode).



    To check that it's open on the current /dev/null file specifically (not /some/chroot/dev/null for instance), on Linux only (where /dev/stdin is implemented as a symlink to the file open on fd 0 instead of a special device which when open acts like a dup(0) in other systems):



    if [ /dev/stdin -ef /dev/null ]; then
    echo stdin is open on /dev/null
    fi


    On non-Linux, you can try:



    if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
    echo stdin is open on /dev/null
    fi





    share|improve this answer

























      up vote
      3
      down vote













      Portably, to check that stdin is the null device (open on /dev/null or not (like a copy of /dev/null)), with zsh (whose stat builtin predates both GNU and FreeBSD stat by the way (not IRIX' though))):



      zmodload zsh/stat
      if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
      echo stdin is open on the null device
      fi


      (note that it doesn't say if the file descriptor was open in read-only, write-only or read+write mode).



      To check that it's open on the current /dev/null file specifically (not /some/chroot/dev/null for instance), on Linux only (where /dev/stdin is implemented as a symlink to the file open on fd 0 instead of a special device which when open acts like a dup(0) in other systems):



      if [ /dev/stdin -ef /dev/null ]; then
      echo stdin is open on /dev/null
      fi


      On non-Linux, you can try:



      if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
      echo stdin is open on /dev/null
      fi





      share|improve this answer























        up vote
        3
        down vote










        up vote
        3
        down vote









        Portably, to check that stdin is the null device (open on /dev/null or not (like a copy of /dev/null)), with zsh (whose stat builtin predates both GNU and FreeBSD stat by the way (not IRIX' though))):



        zmodload zsh/stat
        if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
        echo stdin is open on the null device
        fi


        (note that it doesn't say if the file descriptor was open in read-only, write-only or read+write mode).



        To check that it's open on the current /dev/null file specifically (not /some/chroot/dev/null for instance), on Linux only (where /dev/stdin is implemented as a symlink to the file open on fd 0 instead of a special device which when open acts like a dup(0) in other systems):



        if [ /dev/stdin -ef /dev/null ]; then
        echo stdin is open on /dev/null
        fi


        On non-Linux, you can try:



        if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
        echo stdin is open on /dev/null
        fi





        share|improve this answer












        Portably, to check that stdin is the null device (open on /dev/null or not (like a copy of /dev/null)), with zsh (whose stat builtin predates both GNU and FreeBSD stat by the way (not IRIX' though))):



        zmodload zsh/stat
        if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
        echo stdin is open on the null device
        fi


        (note that it doesn't say if the file descriptor was open in read-only, write-only or read+write mode).



        To check that it's open on the current /dev/null file specifically (not /some/chroot/dev/null for instance), on Linux only (where /dev/stdin is implemented as a symlink to the file open on fd 0 instead of a special device which when open acts like a dup(0) in other systems):



        if [ /dev/stdin -ef /dev/null ]; then
        echo stdin is open on /dev/null
        fi


        On non-Linux, you can try:



        if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
        echo stdin is open on /dev/null
        fi






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        Stéphane Chazelas

        295k54556898




        295k54556898






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f484228%2fhow-to-check-if-stdin-is-dev-null-from-the-shell%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre