How to check if a pipe is empty and run a command on the data if it isn't?












33















I have piped a line in bash script and want to check if the pipe has data, before feeding it to a program.



Searching I found about test -t 0 but it doesn't work here. Always returns false.
So how to be sure that the pipe has data?



Example:



echo "string" | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



Unlike Standard/canonical way to test whether foregoing pipeline produced output? the input needs to be preserved to pass it to the program. This generalizes How to pipe output from one process to another but only execute if the first has output? which focuses on sending email.










share|improve this question

























  • Very similar: Make a pipe conditional on non-empty return (on Super User)

    – G-Man
    Feb 1 '17 at 5:35
















33















I have piped a line in bash script and want to check if the pipe has data, before feeding it to a program.



Searching I found about test -t 0 but it doesn't work here. Always returns false.
So how to be sure that the pipe has data?



Example:



echo "string" | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



Unlike Standard/canonical way to test whether foregoing pipeline produced output? the input needs to be preserved to pass it to the program. This generalizes How to pipe output from one process to another but only execute if the first has output? which focuses on sending email.










share|improve this question

























  • Very similar: Make a pipe conditional on non-empty return (on Super User)

    – G-Man
    Feb 1 '17 at 5:35














33












33








33


14






I have piped a line in bash script and want to check if the pipe has data, before feeding it to a program.



Searching I found about test -t 0 but it doesn't work here. Always returns false.
So how to be sure that the pipe has data?



Example:



echo "string" | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



Unlike Standard/canonical way to test whether foregoing pipeline produced output? the input needs to be preserved to pass it to the program. This generalizes How to pipe output from one process to another but only execute if the first has output? which focuses on sending email.










share|improve this question
















I have piped a line in bash script and want to check if the pipe has data, before feeding it to a program.



Searching I found about test -t 0 but it doesn't work here. Always returns false.
So how to be sure that the pipe has data?



Example:



echo "string" | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"


Output: fill



Unlike Standard/canonical way to test whether foregoing pipeline produced output? the input needs to be preserved to pass it to the program. This generalizes How to pipe output from one process to another but only execute if the first has output? which focuses on sending email.







bash shell pipe






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 13 '18 at 10:30









Ciro Santilli 新疆改造中心 六四事件 法轮功

5,02124142




5,02124142










asked Feb 29 '12 at 9:41









zetahzetah

69241019




69241019













  • Very similar: Make a pipe conditional on non-empty return (on Super User)

    – G-Man
    Feb 1 '17 at 5:35



















  • Very similar: Make a pipe conditional on non-empty return (on Super User)

    – G-Man
    Feb 1 '17 at 5:35

















Very similar: Make a pipe conditional on non-empty return (on Super User)

– G-Man
Feb 1 '17 at 5:35





Very similar: Make a pipe conditional on non-empty return (on Super User)

– G-Man
Feb 1 '17 at 5:35










7 Answers
7






active

oldest

votes


















30














There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.



So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.



first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
if [ -z "$first_byte" ]; then
# stuff to do if the input is empty
else
{
printf "\${first_byte# }"
cat
} | {
# stuff to do if the input is not empty
}
fi


The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:



ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
0) echo empty;;
255) echo success;;
*) echo failure;;
esac


test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.






share|improve this answer


























  • OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

    – zetah
    Feb 29 '12 at 11:28











  • It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

    – radiospiel
    Mar 18 '14 at 20:37













  • @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

    – Gilles
    Mar 18 '14 at 20:46











  • IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

    – Stéphane Chazelas
    Mar 18 '14 at 21:43











  • The first line will make the script wait endlessly if there is no input on stdin.

    – Suzana
    May 27 '15 at 0:04



















10














A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.



ifne runs a given command if and only if the standard input is not empty



Note that if the standard input is not empty, it is passed through ifne to the given command






share|improve this answer





















  • 1





    As of 2017, it's not there by default in Mac or Ubuntu.

    – user7000
    Feb 3 '17 at 1:32



















4














You may use test -s /dev/stdin (in an explicit subshell) as well.



# test if a pipe is empty or not
echo "string" |
(test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

echo "string" | tail -n+2 |
(test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

: | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')





share|improve this answer



















  • 7





    Doesn't work for me. Always says pipe is empty.

    – amphetamachine
    Dec 15 '14 at 16:53






  • 2





    Works on my Mac, but not on my Linux box.

    – peak
    Jul 5 '16 at 17:45



















4














check if file descriptor of stdin (0) is open or closed:



[ ! -t 0 ] && echo "stdin has data" || echo "stdin is empty"





share|improve this answer


























  • When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

    – Jakuje
    Jan 31 '18 at 15:40



















3














Old question, but in case someone comes across it as I did: My solution is to read with a timeout.



while read -t 5 line; do
echo "$line"
done


If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.






share|improve this answer































    0














    This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line



    ifne () {
    read line || return 1
    (echo "$line"; cat) | eval "$@"
    }


    echo hi | ifne xargs echo hi =
    cat /dev/null | ifne xargs echo should not echo





    share|improve this answer



















    • 5





      read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

      – Stéphane Chazelas
      May 27 '15 at 8:34



















    0














    This works for me using read -rt 0



    example from original question, with no data:



    echo "string" | tail -n+2 | if read -rt 0 ; then echo has data ; else echo no data ; fi




    share








    New contributor




    user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.




















      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',
      autoActivateHeartbeat: false,
      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%2f33049%2fhow-to-check-if-a-pipe-is-empty-and-run-a-command-on-the-data-if-it-isnt%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      30














      There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.



      So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.



      first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
      if [ -z "$first_byte" ]; then
      # stuff to do if the input is empty
      else
      {
      printf "\${first_byte# }"
      cat
      } | {
      # stuff to do if the input is not empty
      }
      fi


      The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:



      ifne sh -c 'do_stuff_with_input && exit 255'
      case $? in
      0) echo empty;;
      255) echo success;;
      *) echo failure;;
      esac


      test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.






      share|improve this answer


























      • OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

        – zetah
        Feb 29 '12 at 11:28











      • It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

        – radiospiel
        Mar 18 '14 at 20:37













      • @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

        – Gilles
        Mar 18 '14 at 20:46











      • IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

        – Stéphane Chazelas
        Mar 18 '14 at 21:43











      • The first line will make the script wait endlessly if there is no input on stdin.

        – Suzana
        May 27 '15 at 0:04
















      30














      There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.



      So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.



      first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
      if [ -z "$first_byte" ]; then
      # stuff to do if the input is empty
      else
      {
      printf "\${first_byte# }"
      cat
      } | {
      # stuff to do if the input is not empty
      }
      fi


      The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:



      ifne sh -c 'do_stuff_with_input && exit 255'
      case $? in
      0) echo empty;;
      255) echo success;;
      *) echo failure;;
      esac


      test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.






      share|improve this answer


























      • OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

        – zetah
        Feb 29 '12 at 11:28











      • It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

        – radiospiel
        Mar 18 '14 at 20:37













      • @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

        – Gilles
        Mar 18 '14 at 20:46











      • IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

        – Stéphane Chazelas
        Mar 18 '14 at 21:43











      • The first line will make the script wait endlessly if there is no input on stdin.

        – Suzana
        May 27 '15 at 0:04














      30












      30








      30







      There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.



      So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.



      first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
      if [ -z "$first_byte" ]; then
      # stuff to do if the input is empty
      else
      {
      printf "\${first_byte# }"
      cat
      } | {
      # stuff to do if the input is not empty
      }
      fi


      The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:



      ifne sh -c 'do_stuff_with_input && exit 255'
      case $? in
      0) echo empty;;
      255) echo success;;
      *) echo failure;;
      esac


      test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.






      share|improve this answer















      There's no way to peek at the content of a pipe, nor is there a way to read a character to the pipe then put it back. The only way to know that a pipe has data is to read a byte, and then you have to get that byte to its destination.



      So do just that: read one byte; if you detect an end of file, then do what you want to do when the input is empty; if you do read a byte then fork what you want to do when the input is not empty, pipe that byte into it, and pipe the rest of the data.



      first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n)
      if [ -z "$first_byte" ]; then
      # stuff to do if the input is empty
      else
      {
      printf "\${first_byte# }"
      cat
      } | {
      # stuff to do if the input is not empty
      }
      fi


      The ifne utility from Joey Hess's moreutils runs a command if its input is not empty. It usually isn't installed by default, but it should be available or easy to build on most unix variants. If the input is empty, ifne does nothing and returns the status 0, which cannot be distinguished from the command running successfully. If you want to do something if the input is empty, you need to arrange for the command not to return 0, which can be done by having the success case return a distinguishable error status:



      ifne sh -c 'do_stuff_with_input && exit 255'
      case $? in
      0) echo empty;;
      255) echo success;;
      *) echo failure;;
      esac


      test -t 0 has nothing to do with this; it tests whether standard input is a terminal. It doesn't say anything one way or the other as to whether any input is available.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 15 '16 at 8:15

























      answered Feb 29 '12 at 11:21









      GillesGilles

      533k12810721594




      533k12810721594













      • OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

        – zetah
        Feb 29 '12 at 11:28











      • It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

        – radiospiel
        Mar 18 '14 at 20:37













      • @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

        – Gilles
        Mar 18 '14 at 20:46











      • IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

        – Stéphane Chazelas
        Mar 18 '14 at 21:43











      • The first line will make the script wait endlessly if there is no input on stdin.

        – Suzana
        May 27 '15 at 0:04



















      • OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

        – zetah
        Feb 29 '12 at 11:28











      • It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

        – radiospiel
        Mar 18 '14 at 20:37













      • @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

        – Gilles
        Mar 18 '14 at 20:46











      • IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

        – Stéphane Chazelas
        Mar 18 '14 at 21:43











      • The first line will make the script wait endlessly if there is no input on stdin.

        – Suzana
        May 27 '15 at 0:04

















      OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

      – zetah
      Feb 29 '12 at 11:28





      OK, thanks. I'll use temp file. I found in the meantime there is ifne command from moreutils deb package that does exactly that, but it's not on my system.

      – zetah
      Feb 29 '12 at 11:28













      It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

      – radiospiel
      Mar 18 '14 at 20:37







      It should be possible to write a ~10-lines C program which uses select(2) to check whether there is data available from a pipe, and use that one for the shell script. Note that this only works for named pipes though.

      – radiospiel
      Mar 18 '14 at 20:37















      @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

      – Gilles
      Mar 18 '14 at 20:46





      @radiospiel select tells you if a pipe has data now. If the answer is no, it doesn't tell you whether data will come along later.

      – Gilles
      Mar 18 '14 at 20:46













      IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

      – Stéphane Chazelas
      Mar 18 '14 at 21:43





      IIRC on some Unices (HPUX?), stat(2)/fstat(2) on a pipe gives you (in st_size) how much it contains ATM.

      – Stéphane Chazelas
      Mar 18 '14 at 21:43













      The first line will make the script wait endlessly if there is no input on stdin.

      – Suzana
      May 27 '15 at 0:04





      The first line will make the script wait endlessly if there is no input on stdin.

      – Suzana
      May 27 '15 at 0:04













      10














      A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.



      ifne runs a given command if and only if the standard input is not empty



      Note that if the standard input is not empty, it is passed through ifne to the given command






      share|improve this answer





















      • 1





        As of 2017, it's not there by default in Mac or Ubuntu.

        – user7000
        Feb 3 '17 at 1:32
















      10














      A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.



      ifne runs a given command if and only if the standard input is not empty



      Note that if the standard input is not empty, it is passed through ifne to the given command






      share|improve this answer





















      • 1





        As of 2017, it's not there by default in Mac or Ubuntu.

        – user7000
        Feb 3 '17 at 1:32














      10












      10








      10







      A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.



      ifne runs a given command if and only if the standard input is not empty



      Note that if the standard input is not empty, it is passed through ifne to the given command






      share|improve this answer















      A simple solution is to use ifne command (if input not empty). In some distributions, it is not installed by default. It is a part of the package moreutils in most distros.



      ifne runs a given command if and only if the standard input is not empty



      Note that if the standard input is not empty, it is passed through ifne to the given command







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jul 20 '16 at 22:48









      HalosGhost

      3,72592236




      3,72592236










      answered Jul 20 '16 at 22:27









      Nick WirthNick Wirth

      10112




      10112








      • 1





        As of 2017, it's not there by default in Mac or Ubuntu.

        – user7000
        Feb 3 '17 at 1:32














      • 1





        As of 2017, it's not there by default in Mac or Ubuntu.

        – user7000
        Feb 3 '17 at 1:32








      1




      1





      As of 2017, it's not there by default in Mac or Ubuntu.

      – user7000
      Feb 3 '17 at 1:32





      As of 2017, it's not there by default in Mac or Ubuntu.

      – user7000
      Feb 3 '17 at 1:32











      4














      You may use test -s /dev/stdin (in an explicit subshell) as well.



      # test if a pipe is empty or not
      echo "string" |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      echo "string" | tail -n+2 |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      : | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')





      share|improve this answer



















      • 7





        Doesn't work for me. Always says pipe is empty.

        – amphetamachine
        Dec 15 '14 at 16:53






      • 2





        Works on my Mac, but not on my Linux box.

        – peak
        Jul 5 '16 at 17:45
















      4














      You may use test -s /dev/stdin (in an explicit subshell) as well.



      # test if a pipe is empty or not
      echo "string" |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      echo "string" | tail -n+2 |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      : | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')





      share|improve this answer



















      • 7





        Doesn't work for me. Always says pipe is empty.

        – amphetamachine
        Dec 15 '14 at 16:53






      • 2





        Works on my Mac, but not on my Linux box.

        – peak
        Jul 5 '16 at 17:45














      4












      4








      4







      You may use test -s /dev/stdin (in an explicit subshell) as well.



      # test if a pipe is empty or not
      echo "string" |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      echo "string" | tail -n+2 |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      : | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')





      share|improve this answer













      You may use test -s /dev/stdin (in an explicit subshell) as well.



      # test if a pipe is empty or not
      echo "string" |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      echo "string" | tail -n+2 |
      (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')

      : | (test -s /dev/stdin && echo 'pipe has data' && cat || echo 'pipe is empty')






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Oct 14 '14 at 9:04









      trent55trent55

      4911




      4911








      • 7





        Doesn't work for me. Always says pipe is empty.

        – amphetamachine
        Dec 15 '14 at 16:53






      • 2





        Works on my Mac, but not on my Linux box.

        – peak
        Jul 5 '16 at 17:45














      • 7





        Doesn't work for me. Always says pipe is empty.

        – amphetamachine
        Dec 15 '14 at 16:53






      • 2





        Works on my Mac, but not on my Linux box.

        – peak
        Jul 5 '16 at 17:45








      7




      7





      Doesn't work for me. Always says pipe is empty.

      – amphetamachine
      Dec 15 '14 at 16:53





      Doesn't work for me. Always says pipe is empty.

      – amphetamachine
      Dec 15 '14 at 16:53




      2




      2





      Works on my Mac, but not on my Linux box.

      – peak
      Jul 5 '16 at 17:45





      Works on my Mac, but not on my Linux box.

      – peak
      Jul 5 '16 at 17:45











      4














      check if file descriptor of stdin (0) is open or closed:



      [ ! -t 0 ] && echo "stdin has data" || echo "stdin is empty"





      share|improve this answer


























      • When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

        – Jakuje
        Jan 31 '18 at 15:40
















      4














      check if file descriptor of stdin (0) is open or closed:



      [ ! -t 0 ] && echo "stdin has data" || echo "stdin is empty"





      share|improve this answer


























      • When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

        – Jakuje
        Jan 31 '18 at 15:40














      4












      4








      4







      check if file descriptor of stdin (0) is open or closed:



      [ ! -t 0 ] && echo "stdin has data" || echo "stdin is empty"





      share|improve this answer















      check if file descriptor of stdin (0) is open or closed:



      [ ! -t 0 ] && echo "stdin has data" || echo "stdin is empty"






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 28 '17 at 19:42

























      answered Aug 26 '17 at 11:13









      mviereckmviereck

      1,1971411




      1,1971411













      • When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

        – Jakuje
        Jan 31 '18 at 15:40



















      • When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

        – Jakuje
        Jan 31 '18 at 15:40

















      When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

      – Jakuje
      Jan 31 '18 at 15:40





      When you pass some data and you want to check if there is some, you pass the FD anyway so this is also not a good test.

      – Jakuje
      Jan 31 '18 at 15:40











      3














      Old question, but in case someone comes across it as I did: My solution is to read with a timeout.



      while read -t 5 line; do
      echo "$line"
      done


      If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.






      share|improve this answer




























        3














        Old question, but in case someone comes across it as I did: My solution is to read with a timeout.



        while read -t 5 line; do
        echo "$line"
        done


        If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.






        share|improve this answer


























          3












          3








          3







          Old question, but in case someone comes across it as I did: My solution is to read with a timeout.



          while read -t 5 line; do
          echo "$line"
          done


          If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.






          share|improve this answer













          Old question, but in case someone comes across it as I did: My solution is to read with a timeout.



          while read -t 5 line; do
          echo "$line"
          done


          If stdin is empty, this will return after 5 seconds. Otherwise it will read all the input and you can process it as needed.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 15 '16 at 4:41









          LaddLadd

          311




          311























              0














              This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line



              ifne () {
              read line || return 1
              (echo "$line"; cat) | eval "$@"
              }


              echo hi | ifne xargs echo hi =
              cat /dev/null | ifne xargs echo should not echo





              share|improve this answer



















              • 5





                read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

                – Stéphane Chazelas
                May 27 '15 at 8:34
















              0














              This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line



              ifne () {
              read line || return 1
              (echo "$line"; cat) | eval "$@"
              }


              echo hi | ifne xargs echo hi =
              cat /dev/null | ifne xargs echo should not echo





              share|improve this answer



















              • 5





                read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

                – Stéphane Chazelas
                May 27 '15 at 8:34














              0












              0








              0







              This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line



              ifne () {
              read line || return 1
              (echo "$line"; cat) | eval "$@"
              }


              echo hi | ifne xargs echo hi =
              cat /dev/null | ifne xargs echo should not echo





              share|improve this answer













              This seems to be a reasonable ifne implementation in bash if you're ok with reading the whole first line



              ifne () {
              read line || return 1
              (echo "$line"; cat) | eval "$@"
              }


              echo hi | ifne xargs echo hi =
              cat /dev/null | ifne xargs echo should not echo






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Sep 23 '14 at 3:10









              Eric WoodruffEric Woodruff

              1414




              1414








              • 5





                read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

                – Stéphane Chazelas
                May 27 '15 at 8:34














              • 5





                read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

                – Stéphane Chazelas
                May 27 '15 at 8:34








              5




              5





              read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

              – Stéphane Chazelas
              May 27 '15 at 8:34





              read will also return false if the input is non-empty but contains no newline character, read does some processing on its input and may read more than one line unless you call it as IFS= read -r line. echo can't be used for arbitrary data.

              – Stéphane Chazelas
              May 27 '15 at 8:34











              0














              This works for me using read -rt 0



              example from original question, with no data:



              echo "string" | tail -n+2 | if read -rt 0 ; then echo has data ; else echo no data ; fi




              share








              New contributor




              user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.

























                0














                This works for me using read -rt 0



                example from original question, with no data:



                echo "string" | tail -n+2 | if read -rt 0 ; then echo has data ; else echo no data ; fi




                share








                New contributor




                user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.























                  0












                  0








                  0







                  This works for me using read -rt 0



                  example from original question, with no data:



                  echo "string" | tail -n+2 | if read -rt 0 ; then echo has data ; else echo no data ; fi




                  share








                  New contributor




                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.










                  This works for me using read -rt 0



                  example from original question, with no data:



                  echo "string" | tail -n+2 | if read -rt 0 ; then echo has data ; else echo no data ; fi





                  share








                  New contributor




                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.








                  share


                  share






                  New contributor




                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  answered 2 mins ago









                  user333755user333755

                  1




                  1




                  New contributor




                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.





                  New contributor





                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






                  user333755 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f33049%2fhow-to-check-if-a-pipe-is-empty-and-run-a-command-on-the-data-if-it-isnt%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

                      濃尾地震

                      How to rewrite equation of hyperbola in standard form

                      No ethernet ip address in my vocore2