How to delete long path names with bash shell script?
June 2, 2008 10:07 PM   Subscribe

BASHFilter! I've got a simple bash script that I've written to clean out a frequently used NAS. I run it every 30 days, it sets proper permissions, removes extraneous files and directories, but it frequently hangs on paths longer than 255 characters.

I'm no bash ninja, so I've been beating my head against a wall trying to figure out how to check path length of directories, and then prompt for either renaming to shorten them, or prompt for deletion. Help me Metafilter!
posted by jackofsaxons to Computers & Internet (13 answers total)
 
This should set you up:
echo "12345" | wc -c
6
posted by aeighty at 10:13 PM on June 2, 2008


Can you post the script to pastebin.com?
posted by PueExMachina at 11:14 PM on June 2, 2008


Why not just pushd to the parent directory, delete the file/directory, and then popd?
posted by sbutler at 11:21 PM on June 2, 2008


dirname will print out just the directory name of whatever path you give it.
posted by philomathoholic at 11:31 PM on June 2, 2008


Response by poster: I posted it here http://pastebin.com/mdde8c1

Don't make fun of it, I'm still learning! :D
posted by jackofsaxons at 12:10 AM on June 3, 2008


File 1 will be a list of stuff you want deleted. It's contents will look like this:
-----
"System Volume Information"
Windows
etc
etc
etc
-----

File two will look like this

-----
#!/bin/sh

echo "What directory would you like to clean? [Example: /media/NAS]: "
read nas_folder
chmod -Rfv $nas_folder

for $delete_file in `cat file1` ; do
find $nas_folder -name $delete_file | xargs rm -r;
done

#rest of script here.
-----


Basically, if you're copying the same stuff over and over, you're doing it wrong.

Also, piping it through xargs is a bit faster. If it starts to get hairy, read the xargs man page.
posted by onedarkride at 3:50 AM on June 3, 2008


onedarkride's looks OK, except it'll barf on filenames with any odd characters that xargs interprets as seperators... if you change the find/xargs line to

find $nas_folder -name $delete_file -print0 | xargs -0 rm -r

(that's a zero in both "-print0" and "-0") find will separate the found items with null characters, and xargs will only treat null characters as record separators...

you'd still be traversing the directory tree once for every filename to delete though, which will screw your run time...

perhaps something like
find $nas_dir \( \( -type f \( \
  -name "a filename to delete" -o \
  -name "another filename to delete" -o \
  -name "delete this filename too" \
  \) \) -o \( -type d \( \
  -name "directory name" -o \
  -name "another directory name" -o \
  -name "directory blah" \
  \) \) \) -print0 | xargs -0 rm -rf
(welcome to find/shell quoting hell, and I hope this doesn't get mangled in posting...)

this does a single traverse looking for directory entries that are either files named in the first block, or directories named in the second block, and then pipes them (with null-char delimiters) to xargs for deletion...

and now someone'll probably post something much more elegant... :(
posted by russm at 4:42 AM on June 3, 2008


hmmm... vaguely mangled... remove the blank lines between every content line...

to be a bit clearer, that's a single find command piped into xargs, and the trailing "\" on each line continues the command to the next line... otherwise it'd be even nastier to look at...
posted by russm at 4:45 AM on June 3, 2008


oh, and if you want to test that it won't go and delete all your important files/directories too, change the "-print0 | xargs -0 rm -rf" into just a plain "-print" to see what it'll be matching...
posted by russm at 4:52 AM on June 3, 2008


in the pastebin, every '-exec' ends with backslash space semicolon. This should be simply backslash semicolon -- you want to escape the semicolon so that it is not interpreted by bash but is given as an argument to find.

Other than that, I don't see anything in those 'find's that could plausibly "hang".
posted by jepler at 5:00 AM on June 3, 2008


ah, there's a thought... in your original script most of the directory finds are exec-ing "rm" not "rm -r", which won't work (you need recursive delete for directories, like the first two have)...
posted by russm at 6:00 AM on June 3, 2008


It might be that it is hitting shell expansion limits with the exec call (rather than being a problem with find per se) but you don't need this: find includes a -delete option.
posted by tallus at 6:01 AM on June 3, 2008


One last thing... whenever using rm in scripts with an unknown argument, always use "rm --". That way, a file that begins with '-' won't screw things up. For example, your delete everything older than 30 days should be:

find $nas_folder -mtime +30 -type d -exec rm -rf -- {} \;
posted by sbutler at 11:26 AM on June 3, 2008


« Older Best Earplugs/Earmuff for sleeping with a snorer?   |   Can I remove the insoles of Adidas sneakers? Newer »
This thread is closed to new comments.