Shell scripting

Hi Guys

I found a script that is doing some cleanups on the server. The script remove the users folders...

Now, I have two users that I don't want the script to remove their folders...The commands used on the scripts is as follows:

rm -rf /home/??*/folder_*
rm -rf /home/?/*/folder_*

What does the ??*/ and /?/* mean?

I want to use an IF statement with OR to make sure that folders for that particular user are not deleted.

If I can understand what the two ??*/ and /?/* does or mean. I would appreciate.

Please help !!!

Thanks in advance...

its wildcard

refer more details from this link

?	any single character, except a leading dot
*	zero or more characters, except a leading dot
[ ]	defines a class of characters ( - for range, ! to exclude)
1 Like

Your two commands recursively remove directories that match the pattern. The patterns are:-

  • /home/??*/folder_* - files and directories called folder_ or anything starting folder_ under /home that the intermediate directory is at least two characters long
  • /home/?/folder_* - files and directories called folder_ or anything starting folder_ under /home that the intermediate directory is exactly one character long

Oddly, this means the same as pattern /home/?*/folder_* when you run them sequentially, however this might have been done if there are many matches and when expanded the overall rm command exceeds the maximum command length. It also ignores anything that matches zero characters for the intermediate directory, such as /home/folder_1

Consider this instead:-

find /home -name "folder_*" -exec echo rm -rf {} \;

This will search for files (be they regular files, pipes, directories, sockets etc.) under /home called or starting folder_ and remove them if you drop the echo

This will, however remove items called /home/robin/saved/folder_1 too.

You can limit this to just look for directories by adding a -type d clause.
You can limit the depth it will search to using the -mindepth & -maxdepth clauses if your version of find supports them. If find doesn't support them, you might have to force it some other way, such as with an extended regular expression of some sort.

I encourage you to safely have a go and tell us if you get stuck. Only let the rm run once you are sure it will do exactly what you want.

Does this help?

Robin

1 Like

You didn't specify, whether you want to use a specific shell for your script. If it is fine for you to use zsh, there is an interesting features which allows you to do globbing, but to exclude certain directory entries. Assuming that the users to exclude are 'stan' and 'olli', you could write something like

setopt local_options extended_glob
for home in /home/(*~(stan|olli))(N)
do
   # Remove entries starting with name 'folder_' below directory $home
   rm -rf $home/folder_*
done

The setopt command turns on the special "exclusion feature", and the (N) ensures that the loop is skipped if no files match the pattern.

2 Likes

A similar thing is possible in (recent) bash with the extglob option set:

shopt -s extglob
for DIR in !(AL|LA)/; do echo $DIR; done

should list ALL directories except AL and LA .

3 Likes