Writing a script that outputs local users and their password expiration date











up vote
2
down vote

favorite












I'm supposed to write a script that outputs local users real name and their password expiration information.



This is what I have at the moment. any help would be appreciated.



$ cat /etc/passwd | grep '/home' | cut -d: -f5 ;chage -l {} | 
fgrep "Password expires"'| column -t









share|improve this question
























  • This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
    – slm
    Nov 25 '14 at 19:52

















up vote
2
down vote

favorite












I'm supposed to write a script that outputs local users real name and their password expiration information.



This is what I have at the moment. any help would be appreciated.



$ cat /etc/passwd | grep '/home' | cut -d: -f5 ;chage -l {} | 
fgrep "Password expires"'| column -t









share|improve this question
























  • This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
    – slm
    Nov 25 '14 at 19:52















up vote
2
down vote

favorite









up vote
2
down vote

favorite











I'm supposed to write a script that outputs local users real name and their password expiration information.



This is what I have at the moment. any help would be appreciated.



$ cat /etc/passwd | grep '/home' | cut -d: -f5 ;chage -l {} | 
fgrep "Password expires"'| column -t









share|improve this question















I'm supposed to write a script that outputs local users real name and their password expiration information.



This is what I have at the moment. any help would be appreciated.



$ cat /etc/passwd | grep '/home' | cut -d: -f5 ;chage -l {} | 
fgrep "Password expires"'| column -t






command-line scripting users password






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 at 20:37









Rui F Ribeiro

38.3k1476127




38.3k1476127










asked Nov 25 '14 at 19:04









John h

112




112












  • This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
    – slm
    Nov 25 '14 at 19:52




















  • This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
    – slm
    Nov 25 '14 at 19:52


















This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
– slm
Nov 25 '14 at 19:52






This shows a method: serverfault.com/questions/295125/… as well as here: stackoverflow.com/questions/12660688/…
– slm
Nov 25 '14 at 19:52












3 Answers
3






active

oldest

votes

















up vote
1
down vote













A better way to get local users might be to see if the user has a valid login shell:



getent passwd | grep -f /etc/shells


Here's something that should work:



getent passwd | grep -f /etc/shells | tr ',' ':' | 
awk -F: '{print $1, $5}' | while read USER NAME
do
echo $NAME:$(chage -l $USER| awk -F': ' '/Password expires/{print $2}')
done | column -ts:


Using xargs, one can do:



getent passwd | grep -f /etc/shells | tr ',' ':' | awk -F: '{print $1, $5}' | 
xargs -L1 bash -c 'echo ${@:2}:$(chage -l $1| awk -F": " "/Password expires/{print $2}")' : |
column -ts:



  • Using tr to replace the , with : lets us lift the full name from the GECOS field directly.


  • column can be given an input delimiter with -s, which lets us keep multi-word names in one column.


  • -L makes xargs use one line of input per command, so that the username and full name are passed to each command.


  • ${@:2} - all the parameters from the second parameter onwards (skipping the first).


Example output:



root                      never
Murukesh Mohanan never
Guest never





share|improve this answer






























    up vote
    0
    down vote













    You can use xargs to iterate through the results like this:



    $ grep '/home' /etc/passwd | cut -d: -f1 | xargs -n1 -I{} chage -l {} | 
    grep "Password expires" | column -t
    Password expires : never


    In this variation we're calling xargs with the -n1 switch so it'll only call chage -l with a single username argument. The -I{} tells xargs to use {} as a macro so that we can mark where we want it to put the arguments when calling chage.






    share|improve this answer





















    • I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
      – John h
      Nov 25 '14 at 20:16










    • There isn't any variable being creates here.
      – slm
      Nov 25 '14 at 21:39










    • @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
      – muru
      Nov 25 '14 at 21:55


















    up vote
    0
    down vote













    cut -d: -f1,3,5 /etc/passwd | while IFS=: read -r user userid fullname
    do
    if [ "$userid" -gt 500 ];
    then
    echo "Full Name: $fullname"
    echo "Password Expiry date: $(chage -l "$user" | head -2 | tail -1)"
    fi
    done


    I am just adding the extra step on checking for the local users as /etc/passwd file normally contains the system users as well which we do not want. Also, I am using a while loop to iterate over the file for better readability.






    share|improve this answer





















      Your Answer








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

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

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


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f169911%2fwriting-a-script-that-outputs-local-users-and-their-password-expiration-date%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote













      A better way to get local users might be to see if the user has a valid login shell:



      getent passwd | grep -f /etc/shells


      Here's something that should work:



      getent passwd | grep -f /etc/shells | tr ',' ':' | 
      awk -F: '{print $1, $5}' | while read USER NAME
      do
      echo $NAME:$(chage -l $USER| awk -F': ' '/Password expires/{print $2}')
      done | column -ts:


      Using xargs, one can do:



      getent passwd | grep -f /etc/shells | tr ',' ':' | awk -F: '{print $1, $5}' | 
      xargs -L1 bash -c 'echo ${@:2}:$(chage -l $1| awk -F": " "/Password expires/{print $2}")' : |
      column -ts:



      • Using tr to replace the , with : lets us lift the full name from the GECOS field directly.


      • column can be given an input delimiter with -s, which lets us keep multi-word names in one column.


      • -L makes xargs use one line of input per command, so that the username and full name are passed to each command.


      • ${@:2} - all the parameters from the second parameter onwards (skipping the first).


      Example output:



      root                      never
      Murukesh Mohanan never
      Guest never





      share|improve this answer



























        up vote
        1
        down vote













        A better way to get local users might be to see if the user has a valid login shell:



        getent passwd | grep -f /etc/shells


        Here's something that should work:



        getent passwd | grep -f /etc/shells | tr ',' ':' | 
        awk -F: '{print $1, $5}' | while read USER NAME
        do
        echo $NAME:$(chage -l $USER| awk -F': ' '/Password expires/{print $2}')
        done | column -ts:


        Using xargs, one can do:



        getent passwd | grep -f /etc/shells | tr ',' ':' | awk -F: '{print $1, $5}' | 
        xargs -L1 bash -c 'echo ${@:2}:$(chage -l $1| awk -F": " "/Password expires/{print $2}")' : |
        column -ts:



        • Using tr to replace the , with : lets us lift the full name from the GECOS field directly.


        • column can be given an input delimiter with -s, which lets us keep multi-word names in one column.


        • -L makes xargs use one line of input per command, so that the username and full name are passed to each command.


        • ${@:2} - all the parameters from the second parameter onwards (skipping the first).


        Example output:



        root                      never
        Murukesh Mohanan never
        Guest never





        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          A better way to get local users might be to see if the user has a valid login shell:



          getent passwd | grep -f /etc/shells


          Here's something that should work:



          getent passwd | grep -f /etc/shells | tr ',' ':' | 
          awk -F: '{print $1, $5}' | while read USER NAME
          do
          echo $NAME:$(chage -l $USER| awk -F': ' '/Password expires/{print $2}')
          done | column -ts:


          Using xargs, one can do:



          getent passwd | grep -f /etc/shells | tr ',' ':' | awk -F: '{print $1, $5}' | 
          xargs -L1 bash -c 'echo ${@:2}:$(chage -l $1| awk -F": " "/Password expires/{print $2}")' : |
          column -ts:



          • Using tr to replace the , with : lets us lift the full name from the GECOS field directly.


          • column can be given an input delimiter with -s, which lets us keep multi-word names in one column.


          • -L makes xargs use one line of input per command, so that the username and full name are passed to each command.


          • ${@:2} - all the parameters from the second parameter onwards (skipping the first).


          Example output:



          root                      never
          Murukesh Mohanan never
          Guest never





          share|improve this answer














          A better way to get local users might be to see if the user has a valid login shell:



          getent passwd | grep -f /etc/shells


          Here's something that should work:



          getent passwd | grep -f /etc/shells | tr ',' ':' | 
          awk -F: '{print $1, $5}' | while read USER NAME
          do
          echo $NAME:$(chage -l $USER| awk -F': ' '/Password expires/{print $2}')
          done | column -ts:


          Using xargs, one can do:



          getent passwd | grep -f /etc/shells | tr ',' ':' | awk -F: '{print $1, $5}' | 
          xargs -L1 bash -c 'echo ${@:2}:$(chage -l $1| awk -F": " "/Password expires/{print $2}")' : |
          column -ts:



          • Using tr to replace the , with : lets us lift the full name from the GECOS field directly.


          • column can be given an input delimiter with -s, which lets us keep multi-word names in one column.


          • -L makes xargs use one line of input per command, so that the username and full name are passed to each command.


          • ${@:2} - all the parameters from the second parameter onwards (skipping the first).


          Example output:



          root                      never
          Murukesh Mohanan never
          Guest never






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 '14 at 20:31

























          answered Nov 25 '14 at 19:57









          muru

          35.2k582155




          35.2k582155
























              up vote
              0
              down vote













              You can use xargs to iterate through the results like this:



              $ grep '/home' /etc/passwd | cut -d: -f1 | xargs -n1 -I{} chage -l {} | 
              grep "Password expires" | column -t
              Password expires : never


              In this variation we're calling xargs with the -n1 switch so it'll only call chage -l with a single username argument. The -I{} tells xargs to use {} as a macro so that we can mark where we want it to put the arguments when calling chage.






              share|improve this answer





















              • I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
                – John h
                Nov 25 '14 at 20:16










              • There isn't any variable being creates here.
                – slm
                Nov 25 '14 at 21:39










              • @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
                – muru
                Nov 25 '14 at 21:55















              up vote
              0
              down vote













              You can use xargs to iterate through the results like this:



              $ grep '/home' /etc/passwd | cut -d: -f1 | xargs -n1 -I{} chage -l {} | 
              grep "Password expires" | column -t
              Password expires : never


              In this variation we're calling xargs with the -n1 switch so it'll only call chage -l with a single username argument. The -I{} tells xargs to use {} as a macro so that we can mark where we want it to put the arguments when calling chage.






              share|improve this answer





















              • I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
                – John h
                Nov 25 '14 at 20:16










              • There isn't any variable being creates here.
                – slm
                Nov 25 '14 at 21:39










              • @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
                – muru
                Nov 25 '14 at 21:55













              up vote
              0
              down vote










              up vote
              0
              down vote









              You can use xargs to iterate through the results like this:



              $ grep '/home' /etc/passwd | cut -d: -f1 | xargs -n1 -I{} chage -l {} | 
              grep "Password expires" | column -t
              Password expires : never


              In this variation we're calling xargs with the -n1 switch so it'll only call chage -l with a single username argument. The -I{} tells xargs to use {} as a macro so that we can mark where we want it to put the arguments when calling chage.






              share|improve this answer












              You can use xargs to iterate through the results like this:



              $ grep '/home' /etc/passwd | cut -d: -f1 | xargs -n1 -I{} chage -l {} | 
              grep "Password expires" | column -t
              Password expires : never


              In this variation we're calling xargs with the -n1 switch so it'll only call chage -l with a single username argument. The -I{} tells xargs to use {} as a macro so that we can mark where we want it to put the arguments when calling chage.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 25 '14 at 19:54









              slm

              245k66505671




              245k66505671












              • I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
                – John h
                Nov 25 '14 at 20:16










              • There isn't any variable being creates here.
                – slm
                Nov 25 '14 at 21:39










              • @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
                – muru
                Nov 25 '14 at 21:55


















              • I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
                – John h
                Nov 25 '14 at 20:16










              • There isn't any variable being creates here.
                – slm
                Nov 25 '14 at 21:39










              • @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
                – muru
                Nov 25 '14 at 21:55
















              I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
              – John h
              Nov 25 '14 at 20:16




              I'd like to retain the same structure in my original posting. is it possible for me to call the chage -l function without creating a variable?
              – John h
              Nov 25 '14 at 20:16












              There isn't any variable being creates here.
              – slm
              Nov 25 '14 at 21:39




              There isn't any variable being creates here.
              – slm
              Nov 25 '14 at 21:39












              @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
              – muru
              Nov 25 '14 at 21:55




              @slm I think OP is talking about the variables (while read a b) that my and Ramesh's answers. OP doesn't want to use variables (dunno why, they're in a subshell and will never affect the main shell), but wants output in a "name expiry-date" table form.
              – muru
              Nov 25 '14 at 21:55










              up vote
              0
              down vote













              cut -d: -f1,3,5 /etc/passwd | while IFS=: read -r user userid fullname
              do
              if [ "$userid" -gt 500 ];
              then
              echo "Full Name: $fullname"
              echo "Password Expiry date: $(chage -l "$user" | head -2 | tail -1)"
              fi
              done


              I am just adding the extra step on checking for the local users as /etc/passwd file normally contains the system users as well which we do not want. Also, I am using a while loop to iterate over the file for better readability.






              share|improve this answer

























                up vote
                0
                down vote













                cut -d: -f1,3,5 /etc/passwd | while IFS=: read -r user userid fullname
                do
                if [ "$userid" -gt 500 ];
                then
                echo "Full Name: $fullname"
                echo "Password Expiry date: $(chage -l "$user" | head -2 | tail -1)"
                fi
                done


                I am just adding the extra step on checking for the local users as /etc/passwd file normally contains the system users as well which we do not want. Also, I am using a while loop to iterate over the file for better readability.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  cut -d: -f1,3,5 /etc/passwd | while IFS=: read -r user userid fullname
                  do
                  if [ "$userid" -gt 500 ];
                  then
                  echo "Full Name: $fullname"
                  echo "Password Expiry date: $(chage -l "$user" | head -2 | tail -1)"
                  fi
                  done


                  I am just adding the extra step on checking for the local users as /etc/passwd file normally contains the system users as well which we do not want. Also, I am using a while loop to iterate over the file for better readability.






                  share|improve this answer












                  cut -d: -f1,3,5 /etc/passwd | while IFS=: read -r user userid fullname
                  do
                  if [ "$userid" -gt 500 ];
                  then
                  echo "Full Name: $fullname"
                  echo "Password Expiry date: $(chage -l "$user" | head -2 | tail -1)"
                  fi
                  done


                  I am just adding the extra step on checking for the local users as /etc/passwd file normally contains the system users as well which we do not want. Also, I am using a while loop to iterate over the file for better readability.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 25 '14 at 19:55









                  Ramesh

                  22.9k31101180




                  22.9k31101180






























                      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%2f169911%2fwriting-a-script-that-outputs-local-users-and-their-password-expiration-date%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Morgemoulin

                      Scott Moir

                      Souastre