LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-26-2023, 03:34 AM   #1
amikoyan
Member
 
Registered: Mar 2021
Distribution: Slackware64 -current
Posts: 316

Rep: Reputation: 169Reputation: 169
bash script to safely and recursively delete files with no extension


I am slowly working my way through KN King's 'C Programming - a modern approach'. I use geany as an IDE, which creates an 'executable' file with no extension when I compile each source file e.g. heapsort.c would create a file called heapsort. I create many such files and it is a pain to track them down and remove them. I wish to keep the source files.
I have the following directory structure
Code:
/home/mik/C/knking/ch_[1-9]
So, seems like a job for a bash script. So, I have created clean.sh:

Code:
#!/bin/sh
find . -type f  ! -name "*.*" -delete
which I have placed in the /home/mik/C/knking directory. The idea is it recursively deletes files with no extension in the knking directory and the chapter directories below... and nowhere else.

I am scared to run it 'as is' - I have visions of deleting crucial system files.

I have tested it without the -delete and it finds the correct files.

My questions are: is it safe to use from the knking directory? Is there a better/safer solution?

Last edited by amikoyan; 07-26-2023 at 03:37 AM.
 
Old 07-26-2023, 06:14 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,863

Rep: Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311
what do you mean by safe here?
(by the way, it is not a shell script, just a single commend)
 
Old 07-26-2023, 06:41 AM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
The . is a shortcut for current working directory. Use the absolute path and regardless of how the script is run only those files in the desired directory will be deleted. Keep a backup of the source code just in case. A regular user only has read execute permissions to system files so it is unlikely to delete them but it would be possible for other files in your home directory.

Last edited by michaelk; 07-26-2023 at 07:02 AM.
 
1 members found this post helpful.
Old 07-26-2023, 08:21 AM   #4
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,798

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Looks good.
Have -print (instead of -delete) and check if the listed things are okay for deletion.

Maybe you can use multiple starting points in find:
Code:
#!/bin/sh
find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print
The more criteria you have the safer it becomes (there is an implicit AND)
Say you do not want to delete files created in the last hour:
Code:
#!/bin/sh
find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -mmin +60 -print

Last edited by MadeInGermany; 07-26-2023 at 08:39 AM.
 
1 members found this post helpful.
Old 07-26-2023, 08:28 AM   #5
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,604

Rep: Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547
Quote:
Originally Posted by amikoyan View Post
I use geany as an IDE, which creates an 'executable' file with no extension when I compile each source file e.g. heapsort.c would create a file called heapsort.
Have you checked whether that's configurable? (It is if you call the C compiler directly.)

It would be far safer to set a specific extension so you can target those specific files.


Quote:
I am scared to run it 'as is' - I have visions of deleting crucial system files.
Consider something like this:
Code:
#!/bin/bash

find /specific/path INSERT_FILTER_HERE -print

read -r -p 'Enter "YES" to delete the specified files'
if [ "$REPLY" == "YES" ]
then

find /specific/path INSERT_FILTER_HERE -delete

else
 echo '(no action taken)'
fi
Obviously, the two find commands should be identical except for the final print/delete action.

If you're super paranoid, you could write a self-referencing check that grep the current file for "find" and if the commands differ, error and exit - but it would be simpler to configure your IDE or create a build script that names the files differently.

 
1 members found this post helpful.
Old 07-26-2023, 08:49 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,863

Rep: Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311
Quote:
Originally Posted by boughtonp View Post
Have you checked whether that's configurable? (It is if you call the C compiler directly.)

It would be far safer to set a specific extension so you can target those specific files.



Consider something like this:
Code:
#!/bin/bash

find /specific/path INSERT_FILTER_HERE -print

read -r -p 'Enter "YES" to delete the specified files'
if [ "$REPLY" == "YES" ]
then

find /specific/path INSERT_FILTER_HERE -delete

else
 echo '(no action taken)'
fi
Obviously, the two find commands should be identical except for the final print/delete action.

If you're super paranoid, you could write a self-referencing check that grep the current file for "find" and if the commands differ, error and exit - but it would be simpler to configure your IDE or create a build script that names the files differently.

Code:
FIND=( find /specific/path INSERT_FILTER_HERE )
"${FIND[@]}" -print
...
"${FIND[@]}" -delete
 
1 members found this post helpful.
Old 07-26-2023, 09:01 AM   #7
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,604

Rep: Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547Reputation: 2547

There's no need to quote an entire post that's directly above your reply.

Arrays are certainly an option to reduce maintenance. I didn't use them previously because I was keeping it /bin/sh compatible (as amikoyan's original script was) - then when checking the code before posting, I discovered read's -p is Bash specific and since they had mentioned Bash already, I made the simplest change.

 
Old 07-26-2023, 09:30 AM   #8
Racho
Member
 
Registered: Oct 2021
Posts: 59

Rep: Reputation: Disabled
You may like this:

Code:
echo > remove_script.sh

while read file; do
    echo rm \"$file\" >> remove_script.sh; 
done < <(find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print)

chmod +x remove_script.sh
And then look inside remove_script.sh before running it.
 
1 members found this post helpful.
Old 07-26-2023, 09:46 AM   #9
amikoyan
Member
 
Registered: Mar 2021
Distribution: Slackware64 -current
Posts: 316

Original Poster
Rep: Reputation: 169Reputation: 169
Quote:
Originally Posted by pan64 View Post
what do you mean by safe here?
I mean not to delete anything outside of knking directory and its subdirectories. michaelk's suggestion of changing . to an absolute path should fix that possibility.
 
Old 07-26-2023, 09:54 AM   #10
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,312
Blog Entries: 3

Rep: Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722Reputation: 3722
Quote:
Originally Posted by amikoyan View Post
I mean not to delete anything outside of knking directory and its subdirectories. michaelk's suggestion of changing . to an absolute path should fix that possibility.
See #6 above. Run find first with -print and then once you are sure of the pattern with -delete or -delete -print.
 
Old 07-26-2023, 10:47 AM   #11
amikoyan
Member
 
Registered: Mar 2021
Distribution: Slackware64 -current
Posts: 316

Original Poster
Rep: Reputation: 169Reputation: 169
Thanks for everyone's helpful suggestions. I have tried this with success:

Code:
#!/bin/sh


find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print

read -r -p 'Enter "YES" to delete the specified files '
if [ "$REPLY" == "YES" ]
then

find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -delete

else
 echo '(no action taken)'
fi
I will try out some of the other ideas when I have more time - e.g. adding a time filter with something like
Code:
-mmin +60 -print
when I have decided on an optimal time based on my use pattern.

Thank again everyone who took time to answer.

Last edited by amikoyan; 07-26-2023 at 10:53 AM.
 
Old 07-26-2023, 12:03 PM   #12
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,798

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Quote:
Originally Posted by Racho View Post
You may like this:

Code:
echo > remove_script.sh

while read file; do
    echo rm \"$file\" >> remove_script.sh; 
done < <(find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print)

chmod +x remove_script.sh
$file should be in quotes immediately and in the generated script,
the whole loop should be redirected to the output file, and
a pipe looks simpler here:
Code:
find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print |
while IFS= read -r file; do
    echo "rm '$file'"
done > remove_script.sh

chmod +x remove_script.sh
And the loop can be replaced by sed
Code:
find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -print |
sed "s/.*/rm '&'/" > remove_script.sh

chmod +x remove_script.sh
 
Old 07-26-2023, 01:51 PM   #13
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,866
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
When practicing, you might name your executables *.exe, e.g.
Code:
gcc -o chapter7.exe -g -W -Wall chapter7.c
./chapter7.exe
...
rm *.exe
 
Old 07-27-2023, 01:51 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,863

Rep: Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311Reputation: 7311
and another way:
Code:
echo "CMD=echo" > remove_script.sh
find /home/mik/C/knking/ch_[1-9] -type f  ! -name "*.*" -exec echo "\$CMD '{}'" \; >> remove_script.sh
check your generated remove script.
And if you are satisfied you can change the first line to
Code:
CMD=rm
or something similar.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Requesting terminal command that (recursively) totals size per file extension and number of files per extension triciasurfer Linux - General 8 08-06-2020 07:08 PM
Shell script to delete folders and files dynamically and recursively rjbaca Linux - General 1 06-21-2010 11:26 AM
[SOLVED] how to rename files recursively, only keeping last x digits plus extension furryspider Programming 2 11-29-2009 12:55 PM
Remove files w/ extension txt recursively spiri Linux - General 4 12-14-2005 03:52 AM
can you apply 2.6.x kernel config to 2.4.x safely/somewhat safely? silex_88 Linux - Software 3 12-09-2005 11:38 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration