Clear contents of specified directories, then return exit status

Hello, this is my first post here.

I'm attempting to write a bash shell script to rm the contents of a directory without deleting the directory, specifically in OS X 10.10 . Here's what I have:

function clear() {
USER="$USER"
DIR=$1

rm -rfv /Users/"$USER"/library/$DIR/*
}

clear caches
clear Saved Application State
clear LaunchAgents

if [ "$?" -eq "0" ]
then
echo "Command succeeded"
exit 0
else
echo "Command failed"
exit 1
fi

It's not actually clearing anything but the caches directory and also stating that my permission is denied on Xamarin Font services or something.

rm: /Users/joshuaevans/library/caches/com.xamarin.fontconfig/84c0f976e30e948e99073af70f4ae876-le32d4.cache-3: Permission denied
rm: /Users/joshuaevans/library/caches/com.xamarin.fontconfig/8d7231e6733a9725c81b40e9f55f11b1-le32d4.cache-3: Permission denied
rm: /Users/joshuaevans/library/caches/com.xamarin.fontconfig/b0a71e6bf6a8a1a908413a823d76e21f-le32d4.cache-3: Permission denied
rm: /Users/joshuaevans/library/caches/com.xamarin.fontconfig/CACHEDIR.TAG: Permission denied
rm: /Users/joshuaevans/library/caches/com.xamarin.fontconfig: Directory not empty

Any suggestions?

What are the permissions on the folders telling you permission denied?

First, make alterations to your code as per the red quotes

function clear() {
USER="$USER"
DIR="$1"

rm -rfv "/Users/$USER/library/$DIR"
}

clear caches
clear "Saved Application State"
clear LaunchAgents

The $DIR/* is superfluous in a find. BUT you are not shielding the spaces in your "Saved Application State" argument.

I suspect the errors in rm are causing the shell-script to end prematurely.

Second, have you examined the permissions of the files?

find /Users/$USER/library/caches/* -ls

Andrew

1 Like

apmcd47, I agree with most of your proposals, but the question of YouNicks was: ... to rm the contents of a directory without deleting the directory . So $DIR/* is not superfluous. So this line should be:

rm -rfv "/Users/$USER/library/$DIR/*"

But this line is really superfluous:

USER="$USER"

And of course: problems with permissions cannot be solved with scripts.

Hi Ivo,
I agree that the USER="$USER" is not needed. And, I agree that when $DIR expands to a string containing spaces, that expansion has to be quoted. But quoting the asterisk will not work unless you are trying to remove a file literally named * . I assume that you really meant:

rm -rfv "/Users/$USER/library/$DIR/"*

Hi YouNicks,
In addition to what has already been said, also be aware that checking $? only tells you the exit code of the last command executed before $? is expanded. You are only checking the exit status of the function call: clear LaunchAgents . There is no test to see whether or not the other two calls to clear succeeded.

Maybe you wanted something more like:

IAm=${0##*/}

function clear() {
	rm -rfv "/Users/$USER/library/$1/"*
}

clear caches &&
    clear 'Saved Application State' &&
    clear LaunchAgents

if [ $? -ne 0 ]
then
	printf '%s: Command failed.\n' "$IAm" >&2
	exit 1
fi
printf '%s: Command succeeded.\n' "$IAm"

Hi Andrew, your quotation remarks are valid, but they are not necessary in the case of the variable assignment, since field splitting and wildcard expansions are not performed when assigning to a variable. Quote removal is performed, so

DIR="$1"

is exactly this same as:

DIR=$1

Shell Command Language:Simple Commands

--
The quotes are only necessary when you want to assign something that has a space in it, or certain special characters.
For example:

var="multiple fields divided by spaces (and for example special characters like parentheses)"

Just an observation...

OSX 10.10.x, and numerous other OSes, have clear as a transient command.

The function clear() overrides the transient command and if the transient command is needed eslewhere in the script in the future it will not work.

Therefore it is not a good idea to create functions with the same name as a transient cammand, (utility).

Better to use something like clr tp avoid errors and confusion...

Just a thought.

A simple example:-

#!/bin/bash

# clear is a transient command, (utility), to clear the screen.
clear

# This function is also called clear...
function clear()
{
	echo "This is the function."
}

# The function gets called NOT the transient cammand.
clear