Basic Bash backup script - linux

I'm still learning how to program in bash and for practice i'm trying to do a "backup script" (quotes because I know this isn't a proper backup) here is the code:
#|/bin/bash
sudo mkdir /home/lucas/bkp
echo "Type the path for the directory you want do save"
read directory
if [-d $directory]; then
sudo cp -R $directory /home/lucas/bkp/
else
echo "Path not found"
fi
But I get an error saying the path saved on variable does not exists and doing the same commands by "hand", directly on the shell everything is fine. Here is the error:
lucas#lucas-Linux:~$ sudo sh ./ex.sh
Type the path for the directory you want do save
/home/lucas/git/
./ex.sh: 7: ./ex.sh: [-d: not found
Path not found

You need to put spaces in your condition, like this :
if [ -d $directory ]; then

Related

Linux script throwing error though it completely looks fine

I have to write Linux script for below question
Write a script that renames files based on the file extension.  The script should prompt the user  for a file extension.  
Next, it should ask the user what prefix to prepend to the file name(s).  By  default the prefix should be the current date in YYYY­MM­DD format.  
So, if the user simply  presses enter the date will be used.  Otherwise, whatever the user entered will be used as the  prefix.  
Next, it should display the original file name and the new name of the file.  Finally, it  should rename the file. 
I wrote below shell script & its throwing error. To me script looks completely fine. Though I am able to write alternative script but Could someone please suggest reason & resolution of error in this script.
Script:
#!/bin/bash
read -p "Please enter a file extension : " EXT
for f in *.${EXT}
do
read -p "Please enter a file prefix (Press ENTER to prefix current Date) :" PREFIX
if [ -z "PREFIX" ]
then
new = "$(date +"%Y-%M-%d")-$(basename ${f})"
mv $f $new
echo "$f renamed to $new"
else
new = "${PREFIX}-${f}"
mv $f $new
echo "$f renamed to $new"
fi
done
Error :
./new.sh: line 13: new: command not found
BusyBox v1.24.2 (2017-05-25 17:33:59 CEST) multi-call binary.
Usage: mv [-fin] SOURCE DEST
or: mv [-fin] SOURCE... DIRECTORY
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY
-f Don't prompt before overwriting
-i Interactive, prompt before overwrite
-n Don't overwrite an existing file
*.png renamed to
[root#localhost ~]#
[root#localhost ~]#
The spaces are spoiling your script during assignment
#new = "$(date +"%Y-%M-%d")-$(basename ${f})"
new="$(date +"%Y-%M-%d")-$(basename ${f})"
also
#new = "${PREFIX}-${f}"
new="${PREFIX}-${f}"
shellcheck is an excellent tool for a basic shell checking

Newbie: Script to change directories

The following is a snippet of a larger script I'm attempting. I just want this part to recognize the argument is a directory and then cd to that directory: i.e ./larj /etc.
#!/bin/ksh
# Filename: larj.sh
if [ $# -gt 1 ]; then
echo "0 or 1 arguments allowed."
exit
fi
if [ -f "$1" ]; then
echo "directory only."
exit
else
if [ -d "$1" ]; then
cd $1
fi
fi
When I run the script with /etc as the argument, it appears nothing happens; it stays in the same directory with no error.
Anyone have any suggestions how to get it to change directories?
Thanks
The cd is taking place within the script's shell.
When the script ends, it's shell exits, and you return to the directory before running the script. In order to change the directory you can
mkdir testdir
. ./your_script.sh testdir
At the end of the script you will be moved at directory testdir.
The problem why you cd can't work is that cd executes in the sub-shell when you execute the script as ./larj /etc. So when you execute the script, it changes the working directory of the subshell and has no impact on the current shell.
So you can execute it as . ./larj /etc.
Refer to Why doesn't “cd” work in a bash shell script?.

Bash script, redirect output to another directory

I have an environment variable containing the name of a directory. I am trying to redirect output from an echo command to a text file in a different directory.
For example
DIR="NewDirectory"
mkdir $DIR
echo "Testing" >> "$DIR\file.txt"
Results in a file named NewDirectory\file.txt in the working directory of the script...what exactly am I missing here? The directory is created without issue, so I am not sure what is going on here.
You have to change \ into /:
DIR="NewDirectory"
mkdir -p $DIR
echo "Testing" >> "$DIR/file.txt"
Changed mkdir -p as suggested by #Jord, because -p means: no error if existing, make parent directories as needed
In linux (or unix for that matter), the directory separator is a slash (/), not a backslash (\):
DIR="NewDirectory"
mkdir $DIR
echo "Testing" >> "$DIR/file.txt"
Your line
echo "Testing" >> "$DIR\file.txt"
should read
echo "Testing" >> "$DIR/file.txt"
as / is the separator in paths in Linux.

prompt list of files before execution of rm

I started using "sudo rm -r" to delete files/directories. I even put it as an alias of rm.
I normally know what I am doing and I am quite experience linux user.
However, I would like that when I press the "ENTER", before the execution of rm, a list of files will show up on the screen and a prompt at the end to OK the deletion of files.
Options -i -I -v does not do what I want. I want only one prompt for all the printed files on screen.
Thank you.
##
# Double-check files to delete.
delcheck() {
printf 'Here are the %d files you said you wanted to delete:\n' "$#"
printf '"%s"\n' "$#"
read -p 'Do you want to delete them? [y/N] ' doit
case "$doit" in
[yY]) rm "$#";;
*) printf 'No files deleted\n';;
esac
}
This is a shell function that (when used properly) will do what you want. However, if you load the function in your current shell then try to use it with sudo, it won't do what you expect because sudo creates a separate shell. So you'd need to make this a shell script…
#!/bin/bash
… same code as above …
# All this script does is create the function and then execute it.
# It's lazy, but functions are nice.
delcheck "$#"
…then make sure sudo can access it. Put it in some place that is in the sudo execution PATH (Depending on sudo configuration.) Then if you really want to execute it precisely as sudo rm -r * you will still need to name the script rm, (which in my opinion is dangerous) and make sure its PATH is before /bin in your PATH. (Also dangerous). But there you go.
Here's a nice option
Alias rm to echo | xargs -p rm
The -p option means "interactive" - it will display the entire command (including any expanded file lists) and ask you to confirm
It will NOT ask about the recursively removed files. But it will expand rm * .o to:
rm -rf * .o
rm -rf program.cc program.cc~ program program.o backup?... # NO NO NO NO NO!
Which is much nicer than receiving the error
rm: .o file not found
Edit: corrected the solution based on chepner comment. My previous solutions had a bug :(
This simple script prompts for a y response before deleting the files specified.
rmc script file:
read -p "ok to delete? " ans
case $ans in
[yY]*) sudo rm "$#" ;;
*) echo "Nothing deleted";;
esac
Invoke thus
./rmc *.tmp
I created a script to do this. The solution is similar to #kojiro's.
Save the script with the filename del. Run the command sudo chmod a=r+w+x del to make the script an executable. In the directory in which you want to save the script, export the path by entering export PATH=$PATH:/path/to/the/del/executable in your '~/.bashrc' file and run source ~/.bashrc.
Here, the syntax of rm is preserved, except instead of typing rm ..., type del ... where del is the name of the bash script below.
#! /bin/bash
# Safely delete files
args=("$#") # store all arguments passed to shell
N=$# # number of arguments passed to shell
#echo $#
#echo $#
#echo ${args[#]:0}
echo "Files to delete:"
echo
n=`expr $N - 1`
for i in `seq 0 $n`
do
str=${args[i]}
if [ ${str:0:1} != "-" ]; then
echo $str
fi
done
echo
read -r -p "Delete these files? [y/n] " response
case $response in
[yY][eE][sS]|[yY])
rm ${args[#]:0}
esac

Bash file shows "ln: command not found"

I'm trying to create a bash script to setup my development environment. The script is running as root but I get the error line 11: ln: command not found
#!/bin/bash
#Require script to run as root - doesn't work - syntax error in conditional expression: unexpected token `;'
#if [[ $(/usr/bin/id -u) -ne 0]]; then
# echo "Script must be run as root";
# exit;
#fi
#PHPMyAdmin
PATH="/etc/apache2/sites-available/phpmyadmin.local";
if [ ! -a PATH ]; then
ln -s /home/user/Ubuntu\ One/htdocs/vhosts/phpmyadmin.local PATH;
a2ensite phpmyadmin.local;
fi
PATH=...
Congratulations, you've clobbered how the shell finds commands. Don't do that.
PATH tells the shell where to look for commands. In your case, it looks for ln somewhere in /etc and predictably doesn't find it there.
You should use a different name.

Resources