How to delete contents of user home dir safely via bash - bash

I am writing a bash script to do a account restore. The contents of the home dir is zipped up using this command.
sudo sh -c "cd /home/$username; zip -0 -FS -r -b /tmp /home/0-backup/users/$username.zip ."
This works as expected.
If the user requests a restore of their data, I am doing the following
sudo sh -c "cd /home/$username; rm -rf *"
Then
sudo -u $username unzip /home/0-backup/users/$username.zip -d /home/$username/
This works as expected.
However you can see the flaw in the delete statement, if the username is not set. We delete all users home dir. I have if statements that do the checking to make sure the username is there. I am looking for some advice on a better way to handle resetting the users account data that isn't so dangerous.
One thought I had was to delete the user account and then recreate it. Then do the restore. I think that this would be less risky. I am open to any suggestions.

Check the parameters first.
Then use && after cd so that it won't execute rm if the cd fails.
if [ -n "$username" ] && [ -d "/home/$username" ]
then
sudo sh -c "cd '/home/$username' && rm -rf * .[^.]*"
fi
I added .[^.]* in the rm command so it will delete dot-files as well. [^.] is needed to prevent it from deleting . (the user's directory) and .. (the /home directory).

Related

Bash cron job on hpanel not locating directory

I have the following code on cron job, it runs but the code does not really do what it supposed to. It does not create the directory plus is does not do anything in the code. Please help check if the way I pointed to the directory is wrong.
#!/bin/bash
NAMEDATE=`date +%F_%H-%M`_`whoami`
NAMEDATE2=`date `
mkdir ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE -m 0755
mysqldump -u u3811*****_boss -p"*******" u3811*****_data | gzip ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/db.sql.gz
echo "This is the database backup for website.com on $NAMEDATE2" |
mailx -a ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/db.sql.gz -s "website.com Database attached" -- mail#gmail.com
chmod -R 0644 ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/*
exit 0
Your NAMEDATE variable needs to be modified a bit, as shown below, for more information about variables in bash see this link
NAMEDATE=$(date +%F_%H-%M"_"$(whoami))
When you issue the mkdir command you will need to pass the -p option to create the complete directory structure if it doesn't exists.
mkdir -p ~/home/u3811numbers/domains/website.com/public_html/cron/backup/files/$NAMEDATE -m 0755
Also, the ~ character on Linux based distributions is used as a shortcut for the home directory of the user that invokes it so, in the line below the result is /home//home/u3811*****/domains/website.com/public_html/cron/backup/files/2020-09-04_23-13_ you can read more about it in here
In you last command before the exit, you might need to pass a wildcard (*) to avoid removing the executable bit on the directory, see below
chmod -R 0644 ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/
The final version of your script will look something like this.
#!/bin/bash
NAMEDATE=$(date +%F_%H-%M"_"$(whoami))
NAMEDATE2=date
mkdir -p ~/home/u3811******/domains/website.com/public_html/cron/backup/files/$NAMEDATE -m 0755
mysqldump -u u3811*****_boss -p"******" u3811*****_data | gzip > ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/db.sql.gz
echo "This is the database backup for website.com on $NAMEDATE2" | mailx -a ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/db.sql.gz -s "website.com Database attached" -- mail#gmail.com
chmod -R 0644 ~/home/u3811*****/domains/website.com/public_html/cron/backup/files/$NAMEDATE/*
To debug a bash script you can always pass the -x flag for more information take a look at this article

File permissions, root bash script, edit by user

I have a script that needs to be ran as root. In this script I create directories and files. The files and directories cannot be modified by the user who ran the script (unless there root of course).
I have tried several solutions found here and other sites, first I tried to mkdir -m 777 the directories as so:
#!/bin/bash
...
#Check execution location
CDIR=$(pwd)
#File setup
DATE=$(date +"%m-%d_%H:%M:%S")
LFIL="$CDIR/android-tools/logcat/logcat_$DATE.txt"
BFIL="$CDIR/android-tools/backup/backup_$DATE"
mkdir -m 777 -p "$CDIR/android-tools/logcat/"
mkdir -m 777 -p "$CDIR/android-tools/backup/"
...
I have also tried touching every created file and directory with the $USER as root, like so:
#!/bin/bash
...
#Check execution location
CDIR=$(pwd)
#File setup
DATE=$(date +"%m-%d_%H:%M:%S")
LFIL="$CDIR/android-tools/logcat/logcat_$DATE.txt"
BFIL="$CDIR/android-tools/backup/backup_$DATE"
mkdir -p "$CDIR/android-tools/logcat/"
mkdir -p "$CDIR/android-tools/backup/"
sudo -u $USER touch "$CDIR/"
sudo -u $USER touch "$CDIR/android-tools/"
sudo -u $USER touch "$CDIR/android-tools/logcat/"
sudo -u $USER touch "$CDIR/android-tools/backup/"
sudo -u $USER touch "$CDIR/android-tools/logcat/logcat_*.txt"
sudo -u $USER touch "$CDIR/android-tools/logcat/Backup_*"
...
I have also tried manually running sudo chmod 777 /android-tools/*, and sudo chmod 777 /* from the script directory, gave no errors, but I still cannot delete the files without root permission.
Heres the full script, It's not done yet. Don't run it with an android device connected to your computer.
http://pastebin.com/F20rLJQ4
touch doesn't change ownership. I think you want chown.
If you're using sudo to run your script, $USER is root, but $SUDO_USER is the user who ran sudo, so you can use that.
If you're not using sudo, you can't trust $USER to be anything in particular. The caller can set it to anything (like "root cat /etc/shadow", which would make your above script do surprising things you didn't want it to do because you said $USER instead of "$USER").
If you're running this script using setuid, you need something safer, like id -u, to get the calling process's legitimate UID regardless of what arbitrary string happens to be in $USER.
If you cover both possibilities by making makestuff.sh like this:
# $SUDO_USER if set, otherwise the current user
caller="${SUDO_USER:-$(id -u)}"
mkdir -p foo/bar/baz
chown -R "$caller" foo
Then you can use it this way:
sudo chown root makestuff.sh
sudo chmod 755 makestuff.sh
# User runs it with sudo
sudo ./makestuff.sh
# User can remove the files
rm -r foo
Or this way (if you want to use setuid so regular users can run the script without having sudo access -- which you probably don't, because you're not being careful enough for that):
sudo chown root makestuff.sh
sudo chmod 4755 makestuff.sh # Danger! I told you not to do this.
# User runs it without sudo
./makestuff.sh
# User can remove the files
rm -r foo

mkdir always creates a file instead a directory

First I want to say that I don't really know what I should look for, here in Stack Overflow and what could be a good query for my problem.
In simple words I want to create a new directory and than do some file operations in it. But with the script that I have crafted I got always a file instead of a directory. It seems to be absolutely regardless how I stick the code together there is always the same result. I hope tat masses can help me with their knowledge.
Here is the script:
#!/bin/bash
DLURL=http://drubuntu.googlecode.com/git'
d7dir=/var/www/d7/'
dfsettings=/var/www/d7/sites/default/default.settings.php
settings=/var/www/d7/sites/default/settings.php
#settiing up drush
drush -y dl drush --destination=/usr/share;
#Download and set up drupal
cd /var/www/;
drush -y dl drupal;
mkdir "$d7dir"; #this is the line that always produces a file instead a directory
# regardless if it is replaced by the variable or entered as
# /var/www/d7
cd /var/www/drup*;
cp .htaccess .gitignore "$d7dir";
cp -r * "$d7dir";
cd "$d7dir";
rm -r /var/www/drup*;
mkdir "$d7dir"sites/default/files;
chmod 777 "$d7dir"sites/default/files;
cp "$dfsettings" "$settings";
chmod 777 "$settings";
chown $username:www-data /var/www/d7/.htaccess;
wget -O $d7dir"setupsite $DLURL/scripts/setupsite.sh; > /dev/null 2>&1
chmod +x /var/www/setupsite;
echo "Login Details following...";
read -sn 1 -p "Press any key to continue...";
bash "$d7dir"setupsite;
chown -Rh $username:www-data /var/www;
chmod 644 $d7dir".htaccess;
chmod 644"$settings";
chmod 644"$dfsettings";
exit
I hope someone got the reason for that.
There are many way to debug a shell-scripting.
Add set -x in your beginning script
Get the return value.
mkdir 'the-directory'
ret=$?
if test $ret -eq 0; then
echo 'Create success.'
else
echo 'Failed to create.'
fi
Set to verbose mode $ mkdir -v 'the-directory'
Try this command $ type mkdir, to checking mkdir command.

Downloading and automatically installing a tgz file

#!/bin/bash
mkdir /tmp
curl -O http://www.mucommander.com/download/nightly/mucommander-current.app.tar.gz /tmp/mucommander.tgz
tar -xvzf /tmp/mucommander.tgz */mucommander.app/*
cp -r /tmp/mucommander.app /Applications
rm -r /tmp
I'm trying to create a shell script to download and extract muCommander to my applications directory on a Mac.
I tried cd into the tmp dir, but then the script stops when I do that.
I can extract all using the -C argument, but the current tgz path is muCommander-0_9_0/mucommander.app, which could change on later builds, so I'm trying to keep it generic.
Can anyone give me pointers where I'm going wrong?
Thanks in advance.
Strip the first path component when you untar the archive, from tar(1):
--strip-components count
(x mode only) Remove the specified number of leading path ele-
ments. Pathnames with fewer elements will be silently skipped.
Note that the pathname is edited after checking inclusion/exclu-
sion patterns but before security checks.
Update
Here is a working bash example of how to, fairly generically, copy the contents of the tgz file to /Applications.
shopt -s nocaseglob
TMPDIR=/tmp
APP=mucommander
TMPAPPDIR=$TMPDIR/$APP
mkdir -p $TMPAPPDIR
curl -o $TMPDIR/$APP.tgz http://www.mucommander.com/download/nightly/mucommander-current.app.tar.gz
tar --strip-components=1 -xvzf $APP.tgz -C $TMPAPPDIR
mv $TMPAPPDIR/${APP}* /Applications
# rm -rf $TMPAPPDIR $TMPDIR/$APP
The rm command is commented out for now, verify that it does no harm before you use it.
The following will update your muCommander.
#for the safety, remove old temporary extraction from the /tmp
rm -rf /tmp/muCommander.app
#kill the running mucommander - you dont want replace the runnung app
ps -ef | grep ' /Applications/muCommander.app/' | grep -v grep | awk '{print $2}' | xargs kill
#download, extract, remove old, move new, open
#each command run only when the previous ended with success
curl http://www.mucommander.com/download/nightly/mucommander-current.app.tar.gz |\
tar -xzf - -C /tmp --strip-components=1 '*/muCommander.app' && \
rm -rf /Applications/muCommander.app && \
mv /tmp/muCommander.app /Applications && \
open /Applications/muCommander.app
Beware, after the '\' must following new line, and not any spaces...

Bash script stops execution in the middle of the script without any error

I have this simple bash script that gets a copy from my dev server:
#!/bin/sh
DATE=`date +%Y-%m-%d_%H%M.%S`
BASEDIR="/var/www/db"
RELEASEDIR="$DATE";
RELEASEDIRFULL="$BASEDIR/releases/$RELEASEDIR"
mkdir -p "$RELEASEDIRFULL"
echo "Chdir to \"$RELEASEDIRFULL\""
cd "$RELEASEDIRFULL"
echo "Getting copy from dev"
ssh dev.example.tld "cd /tmp; cd /sites/db; tar -zcvp --exclude data --exclude scripts -f - *" | tar zxvpf -
ln -s /var/www/db/data data
ln -s /var/www/db/scripts scripts
cd $BASEDIR
rm htdocs; ln -s releases/$RELEASEDIR htdocs
Recently it stopped working properly with no apparent reason. It gets to the ssh line, executes it fine (files appear on live server) but does not proceed with ln commands. If I comment the ssh line out, ln lines will get executed properly.
UPDATE: I noticed that when I'm logged on as www-data and start the script, it completes as expected, without errors.
No time to check up the man page, but looks like your tar input is - * - all files + stdin? Are you meaning -- for suspension of further argument processing (if tar supports that)

Resources