-3

I'm writing a bash script that deletes users that are not permitted within the system, but im running into a problem.

#!/bin/bash
getent passwd {1000..60000} | cut -d: -f1 > allusers.txt;
diff allowedusers.txt allusers.txt > del.user;

for user in "cat del.user";
  do userdel -r $user;
done

When I run it, everything goes smoothly until the userdel command. It just outputs usage of userdel.

Usage: userdel [options] LOGIN

Options:
  -f, --force                   force removal of files,
                                even if not owned by user
  -h, --help                    display this help message and exit
  -r, --remove                  remove home directory and mail spool
  -R, --root CHROOT_DIR         directory to chroot into
  -Z, --selinux-user            remove any SELinux user mapping for the user

No changes are made to users after the script has run. Any help would be appreciated.

Aserre
  • 4,916
  • 5
  • 33
  • 56
Ben B
  • 15
  • 6
  • 1
    are you sure `$user` is not empty ? Try running `echo "user: $user"` inside your for loop to be sure. Also, bash doesn't need `;` at the end of the lines. EDIT : your `user` will be equal to the exact string `cat del.user`. Use a while loop to read your file – Aserre Nov 08 '18 at 15:29
  • This has nothing to do with `userdel` in particular; it's just the command that happens to be getting a different set of arguments than you think you are giving it. – chepner Nov 08 '18 at 15:52
  • 1
    You probably don't have a user on the system named "cat del.user". – Paul Hodges Nov 08 '18 at 16:12

2 Answers2

0

diff produces the result with the number of lines where the difference is found:

:~$ cat 1
User1
User2
User3

$ cat 2
User233
User43
User234
User1

And result is:

$ diff 1 2
0a1,3
> User233
> User43
> User234
2,3d4
< User2
< User3

Instead of diff try grep (to show differences in 2d file) :

grep -v -F -x -f file1 file2

where:

-F, --fixed-strings
              Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.    
-x, --line-regexp
              Select only those matches that exactly match the whole line.
-v, --invert-match
              Invert the sense of matching, to select non-matching lines.
-f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.

Example result is:

 $ grep -v -F -x -f 1 2
    User233
    User43
    User234
malyy
  • 859
  • 5
  • 10
-1

Your user variable is not iterating over the users in the file. It is iterating over the literal string "cat del.user" instead of the contents of the file del.user.

To get the contents of the file, I believe you meant to use a subshell to cat the file:

for user in $(cat del.user); do
  userdel -r $user
done
Tyler Marshall
  • 489
  • 3
  • 9
  • 3
    Because of quoting, it's actually set just to the single string `cat del.user` and performs just a single iteration. Lack of quoting later on then subjects `$user` to word splitting. Your recommendation is not a best practice, though: see [BashFAQ/001](https://mywiki.wooledge.org/BashFAQ/001) and [DontReadLinesWithFor](https://mywiki.wooledge.org/DontReadLinesWithFor). – Benjamin W. Nov 08 '18 at 15:50
  • It's not even *good* practice. – chepner Nov 08 '18 at 15:53
  • Thanks @Benjamin. Corrected from single string. Although I'm not worried about spaces in names because OPs question was about why the userdel command was failing, so I used their userdel command. – Tyler Marshall Nov 08 '18 at 15:59
  • I understand now. Idk why I was using quotes in the first place. This does solve the problem and gets me the output I expected. – Ben B Nov 08 '18 at 16:18