LinuxMicrosoft

Remove Files with Force and Other Bad Ideas

Almost every Linux or Unix person has seen the help forum post from a novice looking for an answer to a frustrating problem and the arrogant fool that responds with “Just type in rm -rf / and it will fix the problem.” For anyone who is part of the “do no harm” technical community, this can make us wish for a way to revoke the arrogant fool’s privileges to the internet— permanently.

Recycling Commands

This leads me to a great post from Carlos Robles this last week on using aliases with docker commands. As with many command line utilities, certain commands and arguments are re-used, but may or may not have safety protocols built in to protect you from human error. When considering the use of rm -rf and that docker may be the first experience with it for SQL DBAs, we should consider the difference in using it with the docker utility and how it is used in file management.

The rm -rf file management utility breaks down to remove with the -rf standing for recursive and force. The arguments are important, as this states to follow through the entire directory and any sub-directories and force removal files. As I teach everyone in my Linux sessions- Linux treats EVERYTHING AS A FILE.

If we run through the example Carlos suggested for removing Docker containers, but with my own spin on it, this is what we’d experience:

Note what was done in the above example:

  • I wrote the alias to the .bash_profile
  • I executed my .bash_profile to put the change into effect.
  • I then listed out my containers
  • I used the alias to remove the Kellyn container
  • Lastly, I attempted to run the alias without an argument of container name or ID. Note that it failed as safety protocols are written into the utility.

If this is the first introduction to rm -rf, you might think this is how it works everywhere, which leaves you in a vulnerable state as an administrator in the Linux world. If we create a second example of log files being written to the $home/dockerlogs/ directory and you, as the administrator are expected to remove files on a regular interval, you might want to create an alias to eliminate some of the writing.

  1. Using alias’ save time
  2. Using alias’ may remove the awareness of the dangers of the command underneath it.

Using our steps from the first example, if we did the same type of alias work for it:

  • Write the alias rmlogs=’rm -rf ~/dockerlogs’ to the .bash_profile
  • It will now be in the .bash_profile whenever we log in.
  • We list out our files in the ~/dockerlogs directory
  • We then issue the command rmlogs/…. But at that moment, we accidently hit the enter button…or our coworker throws some papers on our desk and it hits the enter key….or we’re at home and our cat jumps onto the keyboard….you get the idea.
  • We now face that all log files have been forcefully removed from the directory.

How do we avoid these types of dangers with the Linux command rm -rf with its more pertinent dangers at the OS level where protocols haven’t been built in like the docker utility?

Build a Script

You can create a bash script, (or Powershell, but in my example, I’m going to use BASH because, well, I’m a Linux person, this is what we do…😊) This shell script will expect an argument to be passed for a file name and if it isn’t, then it will fail:

#/bin/bash
set -euo pipefail
IFS=$'\n\t'
usage() { echo "Usage: $0 -f <filename>" 1>&2; exit 1; }
declare filename=""
while getopts ":f:" arg; do
case "${arg}" in
   f)filename=${OPTARG};;
   esac
   done
shift $((OPTIND-1))
rm -rf ../dockerlogs/${filename}

This script would be executed as follows:

$ ./rmlogs.sh <filename>

If you don’t include the filename with the command, it will fail. If you still want to use an alias, you can add one:

alias rmlogs = ~/scripts/rmlogs.sh

Just Don’t

The second way is to NOT USE RM -RF in the first place. The FIND command can be used to remove files and can also be used in an alias, (or script) if still desired.

cat .bash_profile << EOF
export filename=dockerdummy.txt
alias rmlogs=’find ~/dockerlogs/$filename -delete’
EOF

Execute my bash profile:

~/.bash_profile

The command would then require me to set the file name and then run the rmlogs alias:

filename=dockerlogs4.txt
rmlogs

You could also turn this into a script, as I stated above. In Linux, it’s always better to be safe then sorry. No one wants to explain how you deleted an entire directory of files or even worse.

 

 

 

Kellyn

http://about.me/dbakevlar