Remove empty folder in bash script?
November 3, 2016 12:52 PM   Subscribe

I need help with a bash script removing empty folders after it completes. I have no idea what I'm doing! Details within.

Here's the script I run on new files in a folder:

======

#!/bin/bash

cd "$1"

for files in *; do
[ ! -f "$3.${files##*.}" ] && mv -v "$files" "/Volumes/NETWORKDRIVE/$3.${files##*.}"
done

======

It takes a file in a folder, renames it to the folder's name, and moves the bare file (not in a folder) to a mounted network volume.

So FILENAME.XYZ in FOLDERNAME becomes FOLDERNAME.XYZ in /Volumes/NETWORKDRIVE

The problem is that it leaves behind the empty folder in the original directory. How can I delete the empty folder after the file is moved? I bumbled through making this from stuff I found in forums, but I'm nervous about removing folders because of how wrong that could go for me. If it matters, I'm on an Apple running MacOS Sierra.

Thanks for any help you can provide.
posted by bluecore to Computers & Internet (9 answers total)
 
if you're certain it's empty, the $1 will never be passed in incorrectly etc, you can rm -rf the folder.

Or a more safer, "rmdir $1" (which is probably the better answer)

(you cd to $1, so alter the rmdir based on if $1 is a local or absolute path etc etc)
posted by k5.user at 1:06 PM on November 3, 2016 [3 favorites]


The problem is that at the end of the script, you're still in the folder you wish to delete, and you can't delete a folder that's being used (such as having it be the current directory). So cd out of it first, say to its parent, then rmdir that directory. E.g.
cd ..
rmdir "$1"

posted by kindall at 1:06 PM on November 3, 2016 [3 favorites]


If you just use "rmdir FOLDERNAME" without options, it will fail if there is anything in the directory.
posted by tracer at 1:06 PM on November 3, 2016 [4 favorites]


Add:

cd ..
rmdir "$1"


On preview, I see I was beaten to the punch.
posted by ndfine at 1:08 PM on November 3, 2016


As others have said, rmdir directory will delete a directory if it is empty and you have permissions to do so (and it is not your current directory).

If $1 is the directory you are trying to remove then
cd .. && rmdir $1
will do what you want

You bash script is uncommented and has no error handling, what if the mv fails? $1 does not exist? the destination fills up? Also what is $3 and where is $2.

While testing your script place the word echo before mv, this will print out actions without actually renaming anything
posted by epo at 1:11 PM on November 3, 2016


epo: You bash script is uncommented and has no error handling, what if the mv fails? $1 does not exist? the destination fills up? Also what is $3 and where is $2.

I'm embarrassed to admit I don't know what any of this does:

[ ! -f "$3.${files##*.}" ] &&

I guess the $3 variable is left over from a larger script out of which I pulled it. The script was working, but should I just remove all instances of "$3." ?
posted by bluecore at 1:53 PM on November 3, 2016


$1 could be dirs/foo1 - in that event, cd .. would fail to rm the directory.

After your for loop, I'd do
cd -
rmdir $1
please do not do "rm -r" for a small script which doesn't do a tonne of sanity checking of your variables. I've had to clean up after people have "rm -r /" (and once mv /$typoedVariableName/* /var/tmp/. (because yeah, one should always be root)) because of accidents. Even if you're not root, "rm -rf $variable" should only be used when you've done a lot of work to sanity check inputs.
posted by nobeagle at 2:17 PM on November 3, 2016 [2 favorites]


Start from scratch. Tell us what are the requirements for the script? What problems are you trying to solve?
posted by Joe Chip at 8:39 PM on November 3, 2016


The thing to understand about bash scripting is that it's a way to string together simpler commands into something to meet your need. The commands that you can use are typically programs, which have manual pages which you can read to see how to use them. For example you're using the cd and mv commands and you can run man mv to find out what the -v flag means. Somewhat obscurely [ is also a command, also known as test. bash itself provides control structures for organizing the flow of your script, in your example you have for in do and done which is used to loop over one element at a time. There are other control structures like if and while also built-in to bash. The bash man page (man bash) details all of these, plus what is the meaning of !, &&, and * in your example, and the syntax of strings and variables. Investing a little time in learning the basics of shell scripting will have large payoff over the course of your life in being able to automate repetitive file manipulation and text processing tasks.
posted by Joe Chip at 9:23 PM on November 3, 2016 [1 favorite]


« Older What do I need to wash after we picked up a tick?   |   Please help me ID this actor. Newer »
This thread is closed to new comments.