Confirming a bash script is in the right folder with wildcards? - bash

Can an if statement in a bash script confirm its current folder based on wildcards?
I am making a script to quickly place a drupal site in maintenance mode, ask if you want to keep the .htaccess file, keep the sites folder and the .htaccess file (if requested), update modules and the database then take the site out of maintenance mode. I have accomplished the above, but for ease of use, I would like to have one master script for all site folders, stored in a central location.
Here is my script that works as designed:
#/bin/bash
CWD=$(pwd)
cd $CWD
echo $CWD
if [ $CWD = "/var/www/vhosts/specific.site.folder" ]; then
echo "Updating drupal core files"
read -r -p "do you need to keep the .htaccess file? [y/N]" response
if [ $response = y ]
then
/usr/local/bin/drush vset maintenance_mode 1
mv ./.htaccess ../.htaccess
mv ./sites ../sites
rm -rf *
cp -R /sources/drupal/* ./
mv ../sites ./sites
mv ../.htaccess ./.htaccess
chown -R httpd:httpd *
/usr/local/bin/drush up && /usr/local/bin/drush updb
/usr/local/bin/drush vset maintenance_mode 0
elif [ $response = n ]
then
/usr/local/bin/drush vset maintenance_mode 1
mv ./sites ../sites
rm -rf *
cp -R /sources/drupal/* ./
mv ../sites ./sites
chown -R httpd:httpd *
/usr/local/bin/drush up && /usr/local/bin/drush updb
/usr/local/bin/drush vset maintenance_mode 0
else
echo "Response must be either y or n"
fi
else
echo "not in a web directory, exiting"
fi
What I would like is for the same script, but something like:
if [ $CWD = "/var/www/vhosts/*" ]; then
This did not work. I would like this to work so that the same script can run for any site, but keep other directories safe, including subdirectories on the site folder itself.
If there are better ways to do anything I have there, please suggest them.
the servers that this is intended to run on are based on centos 6, but it may need to be used on a debian based machine at some point, if anything needs changing please also let me know.

First, you need to use the [[ command; [ does not do pattern matching. Second, the asterisk needs to be unquoted to be treated as a pattern metacharacter, rather than a literal asterisk.
if [[ $CWD = "/var/www/vhosts/"* ]]; then

Related

Copying file between servers

i'm trying to create a simple script that will copy files from server1 to server 2 or from server 2 to server1(depends where i run the script from)
I created a script that should recognize on which server I am, take the source folder and destination folder and execute.
for example
sh script.sh /home/test /destest
should cop y files from test folder to the other server to destest folder
but something is not working for me, I keep getting
No such file or directoryscp:
any ideas?
#!/bin/bash
SRC1=$1
DEST=$3
BOX=$(hostname)
if [ $BOX=server1 ]; then
sudo scp $SRC1 server2:\ $DEST
else
sudo scp -v $SRC1/* server1:\ $DEST
fi
Don't put a space after server1: and server2:.
You need a space around = in the if test.
You should almost always quote variables, in case the value contains whitespace, unless you actually want to split it into separate arguments.
#!/bin/bash
SRC1=$1
DEST=$3
BOX=$(hostname)
if [ "$BOX" = server1 ]; then
sudo scp "$SRC1" "server2:$DEST"
else
sudo scp -v "$SRC1"/* "server1:$DEST"
fi
This is my fixed script that is now working :)
#!/bin/bash
BOX=$(hostname)
if [ "$BOX" = server1 ]; then
sudo scp "$1" user#server2:\ "$2"
else
sudo scp "$1"/* user#server1:\ "$2"
fi

Bash - check if sub directory contains folder

What I am trying to do:
I want every directory in the home folder to contain a shared folder where I will put some shared files for everyone to read. I also stored the shared folder in home. The directory structure looks like this:
home
---user1
------shared
------someFolder
---user2
------someFolder
---shared
I want to make sure I am not inserting a link to the shared folder inside itself. I also want to check if the folders have a link to the shared folder. If it already has a link then do nothing. If it does not have a link then create one.
Here is my code:
for d in */ ; do
if [ "$d" != "shared/" ]
then
shared_exists=false
for e in "$d"*/; do
#echo "$e"
if [ "$e" = $d"shared/" ]
then
shared_exists=true
fi
done
if [ "$shared_exists" = true ]
then
echo "shared exists in $d"
else
echo "Shared does not exist in $d"
sudo ln -s /home/shared/ /home/"$d"
fi
fi
done
Is this the correct way or is there a better way of doing this?
You can refactor that code to this much shorter code:
shopt -s extglob nullglob
cd /home
for d in !(shared)/; do
[[ ! -e "$d"shared ]] && ln -s "$PWD/shared" "$d"shared
done

How can I check if a given directory is accessible?

I am currently writing a script that will list all specific files in a directory. What I need the script to do is to verify that the directory is accessible. I am currently using this bit of code:
# variable used to get the file permissions of the given directory
perm=$(stat -c %a "$dir_name")
if [ "$perm" != "755" -o "$perm" != "777" ]; then
echo ERROR: "Directory $dir_name cannot be accessed check permissions"
echo USAGE: "ass2 <directory>"
exit 3
fi
This will work for checking if they have those specific octal permissions, but I was wondering if there is any other way to check if the directory is accessible or not, and to return an error if it isn't.
Use Bash Conditional Expressions
On Unix and Linux, practically everything is a file...including directories! If you don't care about execute or write permissions, you can simply check whether a directory is readable with the -r test. For example:
# Check if a directory is readable.
mkdir -m 000 /tmp/foo
[[ -r /tmp/foo ]]; echo $?
1
You can also check whether a file is a traversable directory in a similar way. For example:
# Check if variable is a directory with read and execute bits set.
dir_name=/tmp/bar
mkdir -m 555 "$dir_name"
if [[ -d "$dir_name" ]] && [[ -r "$dir_name" ]] && [[ -x "$dir_name" ]]; then
: # do something with the directory
fi
You can make the conditionals as simple or as complex as you like, but you don't have to compare octals or parse stat just to check permissions. Bash conditionals can do the job directly.

Recursively copying a file into multiple directories, if a directory does not exist in Bash

so I need to copy the file /home/servers/template/craftbukkit.jar into every folder inside of /home/servers, Ex. /home/servers/server1, /home/servers/server2, etc.
But I only want to do it if /home/servers/whateverserveritiscurrentlyon/mods does not exsist. This is what I came up with and was wondering if it will work:
echo " Script to copy a file to all server directories, only if mods does not exist in that directory"
for i in /home/servers/*/; do
if [ ! -d "$i/mods" ]; then
cp -f /home/servers/template/craftbukkit.jar "$i"
fi
done
echo " completed script ..."
Looks like it should work. To non-destructively test, change the cp -f ... line to say echo cp -f ... and review the output.
It could also be somewhat shortened, but it wouldn't affect efficiency much:
for i in /home/servers/*/
do
[[ -d "${i}/mods" ]] || cp -f /home/servers/template/craftbukkit.jar "${i}/."
done

Bash script to safely create symlinks?

I'm trying to store all my profile configuration files (~/.xxx) in git. I'm pretty horrible at bash scripting but I imagine this will be pretty straight forward for you scripting gurus.
Basically, I'd like a script that will create symbolic links in my home directory to files in my repo. Twist is, I'd like it warn and prompt for overwrite if the symlink will be overwriting an actual file. It should also prompt if a sym link is going to be overwritten, but the target path is different.
I don't mind manually editing the script for each link I want to create. I'm more concerned with being able to quickly deploy new config scripts by running this script stored in my repo.
Any ideas?
The ln command is already conservative about erasing, so maybe the KISS approach is good enough for you:
ln -s git-stuff/home/.[!.]* .
If a file or link already exists, you'll get an error message and this link will be skipped.
If you want the files to have a different name in your repository, pass the -n option to ln so that it doesn't accidentally create a symlink in an existing subdirectory of that name:
ln -sn git-stuff/home/profile .profile
...
If you also want to have links in subdirectories of your home directory, cp -as reproduces the directory structure but creates symbolic links for regular files. With the -i option, it prompts if a target already exists.
cp -i -as git-stuff/home/.[!.]* .
(My answer assumes GNU ln and GNU cp, such as you'd find on Linux (and Cygwin) but usually not on other unices.)
The following has race conditions, but it is probably as safe as you can get without filesystem transactions:
# create a symlink at $dest pointing to $source
# not well tested
set -e # abort on errors
if [[ ( -h $dest && $(readlink -n "$dest") != $source ) || -f $dest || -d $dest ]]
then
read -p "Overwrite $dest? " answer
else
answer=y
fi
[[ $answer == y ]] && ln -s -n -f -v -- "$source" "$dest"

Resources