Correct a test in a bash script, to echo only if every file found meets the specified test condition












2














for x in $(ls -ll <path to files> | awk '{ print $3,$4 }' | tail -n +2) ; do 
if [ "${x}" != "root" ] ; then
echo "Fail"
break
else
echo "Pass"
fi
done


Now, this prints "Pass" for every file it finds. I want to print "Pass" if all files are owned by root, and print "Fail" if any user or group in list is not root.










share|improve this question





























    2














    for x in $(ls -ll <path to files> | awk '{ print $3,$4 }' | tail -n +2) ; do 
    if [ "${x}" != "root" ] ; then
    echo "Fail"
    break
    else
    echo "Pass"
    fi
    done


    Now, this prints "Pass" for every file it finds. I want to print "Pass" if all files are owned by root, and print "Fail" if any user or group in list is not root.










    share|improve this question



























      2












      2








      2







      for x in $(ls -ll <path to files> | awk '{ print $3,$4 }' | tail -n +2) ; do 
      if [ "${x}" != "root" ] ; then
      echo "Fail"
      break
      else
      echo "Pass"
      fi
      done


      Now, this prints "Pass" for every file it finds. I want to print "Pass" if all files are owned by root, and print "Fail" if any user or group in list is not root.










      share|improve this question















      for x in $(ls -ll <path to files> | awk '{ print $3,$4 }' | tail -n +2) ; do 
      if [ "${x}" != "root" ] ; then
      echo "Fail"
      break
      else
      echo "Pass"
      fi
      done


      Now, this prints "Pass" for every file it finds. I want to print "Pass" if all files are owned by root, and print "Fail" if any user or group in list is not root.







      bash shell-script






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 7 '18 at 20:16









      K7AAY

      380319




      380319










      asked Dec 7 '18 at 16:34









      Caleb Hoch

      111




      111






















          5 Answers
          5






          active

          oldest

          votes


















          6














          If you want to find out if all files in your are owned by root and belong to group root, use find:



          find <path to files> ! -user root -or ! -group root -print


          If anything is returned, that file either is not owned by root, or does not belong to the group root. You can then put that into a conditional clause to print out Pass or Fail.



          [[ "$(find <path to files> ! -user root -or ! -group root -print)" == "" ]] && echo "Pass" || echo "Fail"


          Hope this helps.






          share|improve this answer

















          • 1




            possibly with a "-maxdepth 1" if recursion isn't desired
            – Grump
            Dec 7 '18 at 16:50



















          5














          First, you shouldn't parse the output of ls and its variations. You can go about this using stat:



          $ stat -c%U-%G ./*
          tomasz-tomasz
          tomasz-tomasz
          tomasz-tomasz


          As you can see, the result is a reliable list of two words concatenated, which you can operate on to get the result wanted. Put it into a loop, and there you go:



          PASS=true
          for i in $(stat -c%U-%G ./*); do
          if ! [[ "$i" == root-root ]]; then
          PASS=false; break
          fi
          done
          if "$PASS"; then
          echo Pass
          else
          echo Fail
          fi


          The value of i needs to be root-root for the loop to get to its end with the switch unchanged.



          Replace ./* with the_dir/* to test another location.



          The - separator is needed, because, as Grump noted in the comments, The string comparison may fail if the file is owned by 'roo' and in the group 'troot', so a separator would still be a good thing.



          Familiarise yourself with this: Why *not* parse `ls` (and what do to instead)?






          share|improve this answer























          • the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
            – kbolino
            Dec 7 '18 at 22:57










          • @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
            – Tomasz
            Dec 7 '18 at 23:00










          • Fair enough, I don't think groups can be named the empty string.
            – kbolino
            Dec 7 '18 at 23:21










          • Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
            – kbolino
            Dec 8 '18 at 0:00










          • @kbolino Agreed.
            – Tomasz
            Dec 8 '18 at 2:03



















          2














          How about



          [ 1 = $({ echo root:root; stat -c"%U:%G" *; } | sort -u | wc -l) ] && echo PASS || echo FAIL


          EDIT: or



          [ -z $(stat -c"%U:%G" * | grep -vm1 root:root) ] && echo PASS || echo FAIL





          share|improve this answer























          • Smart, but a short-circuit break after the first fail is a big optimisation.
            – Tomasz
            Dec 7 '18 at 22:09










          • Admitted. Added another approach that quits after first non-match.
            – RudiC
            Dec 7 '18 at 22:23










          • Non-match of what? Is it not the same thing?
            – Tomasz
            Dec 7 '18 at 23:02










          • grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
            – RudiC
            Dec 8 '18 at 12:35



















          0














          The way I would do it is probably



          found=$(find <path to files> -maxdepth 1 -not ( -user root -group root ) -printf "x")
          found=${found:+Fail}
          echo ${found:=Pass}


          However, the simplest way of altering your script is:



          found="Pass"

          for x in $(ls -llA <path to files> | awk 'FNR>2{ print $3,$4 }' )
          do
          if [ "${x}" != "root" ]
          then
          found="Fail"
          break
          fi
          done

          echo $found


          here I've added the A flag to catch files that begin with a "."



          Doing it this way, however, is not a good idea as filenames containing a newline will cause unexpected results.






          share|improve this answer































            0














            The output of ls is risky in command lines. I suggest using find for this purpose in the shellscript.




            • The parameters to find -printf are described in man find.

            • The standard output is piped to grep and the exit status is stored in norootfile.

            • The output is also written to a temporary file, and the number of lines is counted and stored in numfile (the number of files found).

            • You can use the option -v 'verbose' to get more details in the output from the shellscript.


            If you want to search also hidden files use find . instead of find *



            If you don't want to search in subdirectories, use -maxdepth 1 in the find command line.



            #!/bin/bash

            if [ "$1" == "-h" ]
            then
            echo "Usage: $0 -h # this help text"
            echo " $0 -v # verbose output"
            exit
            fi

            tmpfil=$(mktemp)

            find * -xtype f -printf "%u:%g %pn" | tee "$tmpfil" | grep -v '^root:root' > /dev/null

            norootsfile=$?
            numfile=$(wc -l "$tmpfil")
            #cat "$tmpfil"

            if [ ${numfile%% *} -eq 0 ]
            then
            echo "No file found; check the current directory"
            elif [ $norootsfile -eq 0 ]
            then
            echo "Fail"
            if [ "$1" == "-v" ]
            then
            echo "----- Found some file(s) not owned or grouped by root"
            echo "user:group file-name --------------------------------"
            grep -v '^root:root' "$tmpfil"
            fi
            else
            echo "Pass"
            if [ "$1" == "-v" ]
            then
            echo "----- Found only files owned or grouped by root"
            fi
            fi
            rm "$tmpfil"





            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',
              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%2f486630%2fcorrect-a-test-in-a-bash-script-to-echo-only-if-every-file-found-meets-the-spec%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              6














              If you want to find out if all files in your are owned by root and belong to group root, use find:



              find <path to files> ! -user root -or ! -group root -print


              If anything is returned, that file either is not owned by root, or does not belong to the group root. You can then put that into a conditional clause to print out Pass or Fail.



              [[ "$(find <path to files> ! -user root -or ! -group root -print)" == "" ]] && echo "Pass" || echo "Fail"


              Hope this helps.






              share|improve this answer

















              • 1




                possibly with a "-maxdepth 1" if recursion isn't desired
                – Grump
                Dec 7 '18 at 16:50
















              6














              If you want to find out if all files in your are owned by root and belong to group root, use find:



              find <path to files> ! -user root -or ! -group root -print


              If anything is returned, that file either is not owned by root, or does not belong to the group root. You can then put that into a conditional clause to print out Pass or Fail.



              [[ "$(find <path to files> ! -user root -or ! -group root -print)" == "" ]] && echo "Pass" || echo "Fail"


              Hope this helps.






              share|improve this answer

















              • 1




                possibly with a "-maxdepth 1" if recursion isn't desired
                – Grump
                Dec 7 '18 at 16:50














              6












              6








              6






              If you want to find out if all files in your are owned by root and belong to group root, use find:



              find <path to files> ! -user root -or ! -group root -print


              If anything is returned, that file either is not owned by root, or does not belong to the group root. You can then put that into a conditional clause to print out Pass or Fail.



              [[ "$(find <path to files> ! -user root -or ! -group root -print)" == "" ]] && echo "Pass" || echo "Fail"


              Hope this helps.






              share|improve this answer












              If you want to find out if all files in your are owned by root and belong to group root, use find:



              find <path to files> ! -user root -or ! -group root -print


              If anything is returned, that file either is not owned by root, or does not belong to the group root. You can then put that into a conditional clause to print out Pass or Fail.



              [[ "$(find <path to files> ! -user root -or ! -group root -print)" == "" ]] && echo "Pass" || echo "Fail"


              Hope this helps.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Dec 7 '18 at 16:49









              Lewis M

              8185




              8185








              • 1




                possibly with a "-maxdepth 1" if recursion isn't desired
                – Grump
                Dec 7 '18 at 16:50














              • 1




                possibly with a "-maxdepth 1" if recursion isn't desired
                – Grump
                Dec 7 '18 at 16:50








              1




              1




              possibly with a "-maxdepth 1" if recursion isn't desired
              – Grump
              Dec 7 '18 at 16:50




              possibly with a "-maxdepth 1" if recursion isn't desired
              – Grump
              Dec 7 '18 at 16:50













              5














              First, you shouldn't parse the output of ls and its variations. You can go about this using stat:



              $ stat -c%U-%G ./*
              tomasz-tomasz
              tomasz-tomasz
              tomasz-tomasz


              As you can see, the result is a reliable list of two words concatenated, which you can operate on to get the result wanted. Put it into a loop, and there you go:



              PASS=true
              for i in $(stat -c%U-%G ./*); do
              if ! [[ "$i" == root-root ]]; then
              PASS=false; break
              fi
              done
              if "$PASS"; then
              echo Pass
              else
              echo Fail
              fi


              The value of i needs to be root-root for the loop to get to its end with the switch unchanged.



              Replace ./* with the_dir/* to test another location.



              The - separator is needed, because, as Grump noted in the comments, The string comparison may fail if the file is owned by 'roo' and in the group 'troot', so a separator would still be a good thing.



              Familiarise yourself with this: Why *not* parse `ls` (and what do to instead)?






              share|improve this answer























              • the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
                – kbolino
                Dec 7 '18 at 22:57










              • @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
                – Tomasz
                Dec 7 '18 at 23:00










              • Fair enough, I don't think groups can be named the empty string.
                – kbolino
                Dec 7 '18 at 23:21










              • Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
                – kbolino
                Dec 8 '18 at 0:00










              • @kbolino Agreed.
                – Tomasz
                Dec 8 '18 at 2:03
















              5














              First, you shouldn't parse the output of ls and its variations. You can go about this using stat:



              $ stat -c%U-%G ./*
              tomasz-tomasz
              tomasz-tomasz
              tomasz-tomasz


              As you can see, the result is a reliable list of two words concatenated, which you can operate on to get the result wanted. Put it into a loop, and there you go:



              PASS=true
              for i in $(stat -c%U-%G ./*); do
              if ! [[ "$i" == root-root ]]; then
              PASS=false; break
              fi
              done
              if "$PASS"; then
              echo Pass
              else
              echo Fail
              fi


              The value of i needs to be root-root for the loop to get to its end with the switch unchanged.



              Replace ./* with the_dir/* to test another location.



              The - separator is needed, because, as Grump noted in the comments, The string comparison may fail if the file is owned by 'roo' and in the group 'troot', so a separator would still be a good thing.



              Familiarise yourself with this: Why *not* parse `ls` (and what do to instead)?






              share|improve this answer























              • the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
                – kbolino
                Dec 7 '18 at 22:57










              • @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
                – Tomasz
                Dec 7 '18 at 23:00










              • Fair enough, I don't think groups can be named the empty string.
                – kbolino
                Dec 7 '18 at 23:21










              • Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
                – kbolino
                Dec 8 '18 at 0:00










              • @kbolino Agreed.
                – Tomasz
                Dec 8 '18 at 2:03














              5












              5








              5






              First, you shouldn't parse the output of ls and its variations. You can go about this using stat:



              $ stat -c%U-%G ./*
              tomasz-tomasz
              tomasz-tomasz
              tomasz-tomasz


              As you can see, the result is a reliable list of two words concatenated, which you can operate on to get the result wanted. Put it into a loop, and there you go:



              PASS=true
              for i in $(stat -c%U-%G ./*); do
              if ! [[ "$i" == root-root ]]; then
              PASS=false; break
              fi
              done
              if "$PASS"; then
              echo Pass
              else
              echo Fail
              fi


              The value of i needs to be root-root for the loop to get to its end with the switch unchanged.



              Replace ./* with the_dir/* to test another location.



              The - separator is needed, because, as Grump noted in the comments, The string comparison may fail if the file is owned by 'roo' and in the group 'troot', so a separator would still be a good thing.



              Familiarise yourself with this: Why *not* parse `ls` (and what do to instead)?






              share|improve this answer














              First, you shouldn't parse the output of ls and its variations. You can go about this using stat:



              $ stat -c%U-%G ./*
              tomasz-tomasz
              tomasz-tomasz
              tomasz-tomasz


              As you can see, the result is a reliable list of two words concatenated, which you can operate on to get the result wanted. Put it into a loop, and there you go:



              PASS=true
              for i in $(stat -c%U-%G ./*); do
              if ! [[ "$i" == root-root ]]; then
              PASS=false; break
              fi
              done
              if "$PASS"; then
              echo Pass
              else
              echo Fail
              fi


              The value of i needs to be root-root for the loop to get to its end with the switch unchanged.



              Replace ./* with the_dir/* to test another location.



              The - separator is needed, because, as Grump noted in the comments, The string comparison may fail if the file is owned by 'roo' and in the group 'troot', so a separator would still be a good thing.



              Familiarise yourself with this: Why *not* parse `ls` (and what do to instead)?







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 7 '18 at 20:20

























              answered Dec 7 '18 at 17:07









              Tomasz

              9,19352965




              9,19352965












              • the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
                – kbolino
                Dec 7 '18 at 22:57










              • @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
                – Tomasz
                Dec 7 '18 at 23:00










              • Fair enough, I don't think groups can be named the empty string.
                – kbolino
                Dec 7 '18 at 23:21










              • Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
                – kbolino
                Dec 8 '18 at 0:00










              • @kbolino Agreed.
                – Tomasz
                Dec 8 '18 at 2:03


















              • the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
                – kbolino
                Dec 7 '18 at 22:57










              • @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
                – Tomasz
                Dec 7 '18 at 23:00










              • Fair enough, I don't think groups can be named the empty string.
                – kbolino
                Dec 7 '18 at 23:21










              • Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
                – kbolino
                Dec 8 '18 at 0:00










              • @kbolino Agreed.
                – Tomasz
                Dec 8 '18 at 2:03
















              the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
              – kbolino
              Dec 7 '18 at 22:57




              the hyphen - is a poor choice of separator since it is a legal character in usernames on at least some systems; the colon : is a better choice and it's what chown uses too
              – kbolino
              Dec 7 '18 at 22:57












              @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
              – Tomasz
              Dec 7 '18 at 23:00




              @kbolino But if there's one hyphen in one username, there would be two total in the product of %U-%G, while root-root has only one. So they would not be equal.
              – Tomasz
              Dec 7 '18 at 23:00












              Fair enough, I don't think groups can be named the empty string.
              – kbolino
              Dec 7 '18 at 23:21




              Fair enough, I don't think groups can be named the empty string.
              – kbolino
              Dec 7 '18 at 23:21












              Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
              – kbolino
              Dec 8 '18 at 0:00




              Actually, empty group name wouldn't matter at all. The only case where the hyphen would be a problem is where the user name you're looking for has a hyphen as then user john-smith in group users would be indistinguishable from user john in group smith-users. The practical relevance of this exception is pretty low, though.
              – kbolino
              Dec 8 '18 at 0:00












              @kbolino Agreed.
              – Tomasz
              Dec 8 '18 at 2:03




              @kbolino Agreed.
              – Tomasz
              Dec 8 '18 at 2:03











              2














              How about



              [ 1 = $({ echo root:root; stat -c"%U:%G" *; } | sort -u | wc -l) ] && echo PASS || echo FAIL


              EDIT: or



              [ -z $(stat -c"%U:%G" * | grep -vm1 root:root) ] && echo PASS || echo FAIL





              share|improve this answer























              • Smart, but a short-circuit break after the first fail is a big optimisation.
                – Tomasz
                Dec 7 '18 at 22:09










              • Admitted. Added another approach that quits after first non-match.
                – RudiC
                Dec 7 '18 at 22:23










              • Non-match of what? Is it not the same thing?
                – Tomasz
                Dec 7 '18 at 23:02










              • grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
                – RudiC
                Dec 8 '18 at 12:35
















              2














              How about



              [ 1 = $({ echo root:root; stat -c"%U:%G" *; } | sort -u | wc -l) ] && echo PASS || echo FAIL


              EDIT: or



              [ -z $(stat -c"%U:%G" * | grep -vm1 root:root) ] && echo PASS || echo FAIL





              share|improve this answer























              • Smart, but a short-circuit break after the first fail is a big optimisation.
                – Tomasz
                Dec 7 '18 at 22:09










              • Admitted. Added another approach that quits after first non-match.
                – RudiC
                Dec 7 '18 at 22:23










              • Non-match of what? Is it not the same thing?
                – Tomasz
                Dec 7 '18 at 23:02










              • grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
                – RudiC
                Dec 8 '18 at 12:35














              2












              2








              2






              How about



              [ 1 = $({ echo root:root; stat -c"%U:%G" *; } | sort -u | wc -l) ] && echo PASS || echo FAIL


              EDIT: or



              [ -z $(stat -c"%U:%G" * | grep -vm1 root:root) ] && echo PASS || echo FAIL





              share|improve this answer














              How about



              [ 1 = $({ echo root:root; stat -c"%U:%G" *; } | sort -u | wc -l) ] && echo PASS || echo FAIL


              EDIT: or



              [ -z $(stat -c"%U:%G" * | grep -vm1 root:root) ] && echo PASS || echo FAIL






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 7 '18 at 22:22

























              answered Dec 7 '18 at 22:00









              RudiC

              4,2041312




              4,2041312












              • Smart, but a short-circuit break after the first fail is a big optimisation.
                – Tomasz
                Dec 7 '18 at 22:09










              • Admitted. Added another approach that quits after first non-match.
                – RudiC
                Dec 7 '18 at 22:23










              • Non-match of what? Is it not the same thing?
                – Tomasz
                Dec 7 '18 at 23:02










              • grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
                – RudiC
                Dec 8 '18 at 12:35


















              • Smart, but a short-circuit break after the first fail is a big optimisation.
                – Tomasz
                Dec 7 '18 at 22:09










              • Admitted. Added another approach that quits after first non-match.
                – RudiC
                Dec 7 '18 at 22:23










              • Non-match of what? Is it not the same thing?
                – Tomasz
                Dec 7 '18 at 23:02










              • grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
                – RudiC
                Dec 8 '18 at 12:35
















              Smart, but a short-circuit break after the first fail is a big optimisation.
              – Tomasz
              Dec 7 '18 at 22:09




              Smart, but a short-circuit break after the first fail is a big optimisation.
              – Tomasz
              Dec 7 '18 at 22:09












              Admitted. Added another approach that quits after first non-match.
              – RudiC
              Dec 7 '18 at 22:23




              Admitted. Added another approach that quits after first non-match.
              – RudiC
              Dec 7 '18 at 22:23












              Non-match of what? Is it not the same thing?
              – Tomasz
              Dec 7 '18 at 23:02




              Non-match of what? Is it not the same thing?
              – Tomasz
              Dec 7 '18 at 23:02












              grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
              – RudiC
              Dec 8 '18 at 12:35




              grep's -m1 option makes it leave after the first match (due to the -v: non-match), i.e. the first line not matching "root:root".
              – RudiC
              Dec 8 '18 at 12:35











              0














              The way I would do it is probably



              found=$(find <path to files> -maxdepth 1 -not ( -user root -group root ) -printf "x")
              found=${found:+Fail}
              echo ${found:=Pass}


              However, the simplest way of altering your script is:



              found="Pass"

              for x in $(ls -llA <path to files> | awk 'FNR>2{ print $3,$4 }' )
              do
              if [ "${x}" != "root" ]
              then
              found="Fail"
              break
              fi
              done

              echo $found


              here I've added the A flag to catch files that begin with a "."



              Doing it this way, however, is not a good idea as filenames containing a newline will cause unexpected results.






              share|improve this answer




























                0














                The way I would do it is probably



                found=$(find <path to files> -maxdepth 1 -not ( -user root -group root ) -printf "x")
                found=${found:+Fail}
                echo ${found:=Pass}


                However, the simplest way of altering your script is:



                found="Pass"

                for x in $(ls -llA <path to files> | awk 'FNR>2{ print $3,$4 }' )
                do
                if [ "${x}" != "root" ]
                then
                found="Fail"
                break
                fi
                done

                echo $found


                here I've added the A flag to catch files that begin with a "."



                Doing it this way, however, is not a good idea as filenames containing a newline will cause unexpected results.






                share|improve this answer


























                  0












                  0








                  0






                  The way I would do it is probably



                  found=$(find <path to files> -maxdepth 1 -not ( -user root -group root ) -printf "x")
                  found=${found:+Fail}
                  echo ${found:=Pass}


                  However, the simplest way of altering your script is:



                  found="Pass"

                  for x in $(ls -llA <path to files> | awk 'FNR>2{ print $3,$4 }' )
                  do
                  if [ "${x}" != "root" ]
                  then
                  found="Fail"
                  break
                  fi
                  done

                  echo $found


                  here I've added the A flag to catch files that begin with a "."



                  Doing it this way, however, is not a good idea as filenames containing a newline will cause unexpected results.






                  share|improve this answer














                  The way I would do it is probably



                  found=$(find <path to files> -maxdepth 1 -not ( -user root -group root ) -printf "x")
                  found=${found:+Fail}
                  echo ${found:=Pass}


                  However, the simplest way of altering your script is:



                  found="Pass"

                  for x in $(ls -llA <path to files> | awk 'FNR>2{ print $3,$4 }' )
                  do
                  if [ "${x}" != "root" ]
                  then
                  found="Fail"
                  break
                  fi
                  done

                  echo $found


                  here I've added the A flag to catch files that begin with a "."



                  Doing it this way, however, is not a good idea as filenames containing a newline will cause unexpected results.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Dec 7 '18 at 17:54

























                  answered Dec 7 '18 at 16:56









                  Grump

                  1665




                  1665























                      0














                      The output of ls is risky in command lines. I suggest using find for this purpose in the shellscript.




                      • The parameters to find -printf are described in man find.

                      • The standard output is piped to grep and the exit status is stored in norootfile.

                      • The output is also written to a temporary file, and the number of lines is counted and stored in numfile (the number of files found).

                      • You can use the option -v 'verbose' to get more details in the output from the shellscript.


                      If you want to search also hidden files use find . instead of find *



                      If you don't want to search in subdirectories, use -maxdepth 1 in the find command line.



                      #!/bin/bash

                      if [ "$1" == "-h" ]
                      then
                      echo "Usage: $0 -h # this help text"
                      echo " $0 -v # verbose output"
                      exit
                      fi

                      tmpfil=$(mktemp)

                      find * -xtype f -printf "%u:%g %pn" | tee "$tmpfil" | grep -v '^root:root' > /dev/null

                      norootsfile=$?
                      numfile=$(wc -l "$tmpfil")
                      #cat "$tmpfil"

                      if [ ${numfile%% *} -eq 0 ]
                      then
                      echo "No file found; check the current directory"
                      elif [ $norootsfile -eq 0 ]
                      then
                      echo "Fail"
                      if [ "$1" == "-v" ]
                      then
                      echo "----- Found some file(s) not owned or grouped by root"
                      echo "user:group file-name --------------------------------"
                      grep -v '^root:root' "$tmpfil"
                      fi
                      else
                      echo "Pass"
                      if [ "$1" == "-v" ]
                      then
                      echo "----- Found only files owned or grouped by root"
                      fi
                      fi
                      rm "$tmpfil"





                      share|improve this answer




























                        0














                        The output of ls is risky in command lines. I suggest using find for this purpose in the shellscript.




                        • The parameters to find -printf are described in man find.

                        • The standard output is piped to grep and the exit status is stored in norootfile.

                        • The output is also written to a temporary file, and the number of lines is counted and stored in numfile (the number of files found).

                        • You can use the option -v 'verbose' to get more details in the output from the shellscript.


                        If you want to search also hidden files use find . instead of find *



                        If you don't want to search in subdirectories, use -maxdepth 1 in the find command line.



                        #!/bin/bash

                        if [ "$1" == "-h" ]
                        then
                        echo "Usage: $0 -h # this help text"
                        echo " $0 -v # verbose output"
                        exit
                        fi

                        tmpfil=$(mktemp)

                        find * -xtype f -printf "%u:%g %pn" | tee "$tmpfil" | grep -v '^root:root' > /dev/null

                        norootsfile=$?
                        numfile=$(wc -l "$tmpfil")
                        #cat "$tmpfil"

                        if [ ${numfile%% *} -eq 0 ]
                        then
                        echo "No file found; check the current directory"
                        elif [ $norootsfile -eq 0 ]
                        then
                        echo "Fail"
                        if [ "$1" == "-v" ]
                        then
                        echo "----- Found some file(s) not owned or grouped by root"
                        echo "user:group file-name --------------------------------"
                        grep -v '^root:root' "$tmpfil"
                        fi
                        else
                        echo "Pass"
                        if [ "$1" == "-v" ]
                        then
                        echo "----- Found only files owned or grouped by root"
                        fi
                        fi
                        rm "$tmpfil"





                        share|improve this answer


























                          0












                          0








                          0






                          The output of ls is risky in command lines. I suggest using find for this purpose in the shellscript.




                          • The parameters to find -printf are described in man find.

                          • The standard output is piped to grep and the exit status is stored in norootfile.

                          • The output is also written to a temporary file, and the number of lines is counted and stored in numfile (the number of files found).

                          • You can use the option -v 'verbose' to get more details in the output from the shellscript.


                          If you want to search also hidden files use find . instead of find *



                          If you don't want to search in subdirectories, use -maxdepth 1 in the find command line.



                          #!/bin/bash

                          if [ "$1" == "-h" ]
                          then
                          echo "Usage: $0 -h # this help text"
                          echo " $0 -v # verbose output"
                          exit
                          fi

                          tmpfil=$(mktemp)

                          find * -xtype f -printf "%u:%g %pn" | tee "$tmpfil" | grep -v '^root:root' > /dev/null

                          norootsfile=$?
                          numfile=$(wc -l "$tmpfil")
                          #cat "$tmpfil"

                          if [ ${numfile%% *} -eq 0 ]
                          then
                          echo "No file found; check the current directory"
                          elif [ $norootsfile -eq 0 ]
                          then
                          echo "Fail"
                          if [ "$1" == "-v" ]
                          then
                          echo "----- Found some file(s) not owned or grouped by root"
                          echo "user:group file-name --------------------------------"
                          grep -v '^root:root' "$tmpfil"
                          fi
                          else
                          echo "Pass"
                          if [ "$1" == "-v" ]
                          then
                          echo "----- Found only files owned or grouped by root"
                          fi
                          fi
                          rm "$tmpfil"





                          share|improve this answer














                          The output of ls is risky in command lines. I suggest using find for this purpose in the shellscript.




                          • The parameters to find -printf are described in man find.

                          • The standard output is piped to grep and the exit status is stored in norootfile.

                          • The output is also written to a temporary file, and the number of lines is counted and stored in numfile (the number of files found).

                          • You can use the option -v 'verbose' to get more details in the output from the shellscript.


                          If you want to search also hidden files use find . instead of find *



                          If you don't want to search in subdirectories, use -maxdepth 1 in the find command line.



                          #!/bin/bash

                          if [ "$1" == "-h" ]
                          then
                          echo "Usage: $0 -h # this help text"
                          echo " $0 -v # verbose output"
                          exit
                          fi

                          tmpfil=$(mktemp)

                          find * -xtype f -printf "%u:%g %pn" | tee "$tmpfil" | grep -v '^root:root' > /dev/null

                          norootsfile=$?
                          numfile=$(wc -l "$tmpfil")
                          #cat "$tmpfil"

                          if [ ${numfile%% *} -eq 0 ]
                          then
                          echo "No file found; check the current directory"
                          elif [ $norootsfile -eq 0 ]
                          then
                          echo "Fail"
                          if [ "$1" == "-v" ]
                          then
                          echo "----- Found some file(s) not owned or grouped by root"
                          echo "user:group file-name --------------------------------"
                          grep -v '^root:root' "$tmpfil"
                          fi
                          else
                          echo "Pass"
                          if [ "$1" == "-v" ]
                          then
                          echo "----- Found only files owned or grouped by root"
                          fi
                          fi
                          rm "$tmpfil"






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Dec 7 '18 at 22:26

























                          answered Dec 7 '18 at 22:20









                          sudodus

                          1,12616




                          1,12616






























                              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.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • 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%2f486630%2fcorrect-a-test-in-a-bash-script-to-echo-only-if-every-file-found-meets-the-spec%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

                              Сан-Квентин

                              8-я гвардейская общевойсковая армия

                              Алькесар