I am getting this error when I run my Bash script:
syntax error: unexpected end of file
Cant really find where the error is, been looking for hours and still get this error.
Here is the script hope some one cant point me in the right direction:
#!/bin/bash
BACKUPDIR=~/backup
SCRIPTDIR=~/respaldar
BACKUPFILE=/respaldo.$(date +%F).bz2
BACKUPHOST=199.21.112.70
COUNT=$(ls $BACKUPDIR | wc -l)
TRESHOLD=7
if [[ ! -e $BACKUPDIR ]]
then
echo "Creating Backup Directory because it doesn\'t exist !"
mkdir ~/backup
COUNT=0
# exit 0
else
COUNT=$(ls $BACKUPDIR | wc -l)
fi
if [[ $COUNT -le $THRESHOLD ]]
then
tar -cjvf $BACKUPDIR/$BACKUPFILE $SCRIPTDIR
if [[ $? -ne 0 ]]; then echo "Problems Creating Backup File;" fi
scp $BACKUPDIR/$BACKUPFILE $BACKUPHOST:
if [[ $? -ne 0 ]]; then echo "Problems Copying Backup File to Backup Host;" fi
fi
#END
Appreciate the help.
I copyed the whole stuff to vi and it spotted the same thing as fedorqui:
if [[ $? -ne 0 ]]; then echo "Problems Creating Backup File;" fi
...
if [[ $? -ne 0 ]]; then echo "Problems Copying Backup File to Backup Host;" fi
The ; is before " and should be after.
I would suggest to use a shorter solution in both cases:
[ $? -ne 0 ] && echo "Problems Creating Backup File">&2 && exit 1
This will exit if tar fails. Or even the more talkative version:
tar -cjvf $BACKUPDIR/$BACKUPFILE $SCRIPTDIR || \
{ echo "Problems Creating Backup File">&2;exit 1;}
Or if You want to see an error message only if the whole process fails:
tar -cjvf $BACKUPDIR/$BACKUPFILE $SCRIPTDIR && \
scp $BACKUPDIR/$BACKUPFILE $BACKUPHOST: || \
{ echo "Backup failed">&2;exit 1;}
Related
I have a problem with pre-commit hook. The first half of the script works, but the second half that checks max size doesn't. Anyone have an idea what the problem is?
#!/bin/bash
REPOS=$1
TXN=$2
MAX_SIZE=10
AWK=/bin/awk
SVNLOOK="/usr/bin/svnlook";
#Put all banned extensions formats in variable FILTER
FILTER=".(iso|exe)$"
# Figure out what directories have changed using svnlook.
FILES=`${SVNLOOK} changed ${REPOS} -t ${TXN} | ${AWK} '{ print $2 }'` > /dev/null
for FILE in $FILES; do
#Get the base Filename to extract its extension
NAME=`basename "$FILE"`
#Get the extension of the current file
EXTENSION=`echo "$NAME" | cut -d'.' -f2-`
#Checks if it contains the restricted format
if [[ "$FILTER" == *"$EXTENSION"* ]]; then
echo "Your commit has been blocked because you are trying to commit a restricted file." 1>&2
echo "Please contact SVN Admin. -- Thank you" 1>&2
exit 1
fi
#check file size
filesize=$($SVNLOOK cat -t $TXN $REPOS $f|wc -c)
if [ "$filesize" -gt "$MAX_SIZE" ]; then
echo "File $f is too large(must <=$MAX_SIZE)" 1>&2
exit 1
fi
done
exit 0
OK, I made a little script to check filesize only
#!/bin/bash
REPOS=$1
TXN=$2
MAX_SIZE=10
AWK=/bin/awk
SVNLOOK="/usr/bin/svnlook";
#check file size
filesize=`${SVNLOOK} changed ${REPOS} -t ${TXN} | wc -c`
if [ "$filesize" -gt "$MAX_SIZE" ]; then
echo "File $filesize is too large" 1>&2
exit 1
fi
echo "File $filesize" 1>&2
exit 0
and when I try co commit file that have 25,5 MB, in output see only 20
File 20 is too large
Why its only 20 ? I think output must be on like 26826864 Bytes
Ok last wariuan of this script is
#!/bin/bash
REPOS=$1
TXN=$2
MAX_SIZE=10
svnlook="/usr/bin/svnlook";
size=$($svnlook filesize -t $TXN $REPOS $file)
if [[ "$size" -gt "$MAX_SIZE" ]] ; then
echo "File is too large" 1>&2
exit 1
fi
exit 0
But it still didnt work. Can someone write the correct variant of this please?
In that case, as I understand correctly, scrypt must look like below. But it still doesn't work, maybe someone knows what the problem is? Then I can add a file of whatever size.
#!/bin/bash
REPOS=$1
TXN=$2
maxsize=-1
svnlook="/usr/bin/svnlook";
svnlook -t $TXN changed | while read status file
do
[[ $status == "D" ]] && continue # Skip Deletions
[[ $file == */ ]] && continue # Skip directories
size=$(svnlook filesize -t $TXN $REPOS $file)
if [ $size -gt $maxsize ]]
then
echo "File '$file' too large to commit" >&2
exit 2
fi
done
exit 0
You made at least 2 errors, outside of code:
Didn't verify output of |wc -c by hand before using in hook (I can't recall format from memory)
Didn't RTFM carefully: piping of $SVNLOOK cat is unnecessary overcomplication, while you have subcommand filesize.
Addition
Code from referenced in my comment topic (re-read it carefully, don't miss cycle for getting every file in transaction)
svnlook -t $TXN changed | while read status file
do
[[ $status == "D" ]] && continue # Skip Deletions
[[ $file == */ ]] && continue # Skip directories
size=$(svnlook filesize -t $TXN $REPOS $file)
if [ $size -gt $maxsize ]]
then
echo "File '$file' too large to commit" >&2
exit 2
fi
done
exit 0
This wariant is working for me :)
#!/bin/bash
REPOS=$1
TXN=$2
MAX_SIZE=20971520
svnlook=/usr/bin/svnlook
AWK=/bin/awk
FILES=`${svnlook} changed -t ${TXN} ${REPOS} | ${AWK} '{print $2}'`
for FILE in $FILES; do
size=`${svnlook} filesize -t ${TXN} ${REPOS} ${FILES}`
if [[ "$size" -gt "$MAX_SIZE" ]] ; then
echo "Your commit has been blocked because you are trying to commit a too large file." 1>&2
exit 1
fi
done
exit 0
I wrote a code for recyclebin file for UNIX. And when i bash recyclebin -i filename,
it reads the getopts passed before the filename and after that it calls test function
and enter into the test function but doesnt enter the for loop inside the function. The program is not going anywhere from there, i am stuck there. Any help what am i doing wrong there
#!bin/bash
### 2. creating directory ~/recyclebin in home if not present
if [[ ! -d $HOME/recyclebin ]]
then
mkdir $HOME/recyclebin
#touch $HOME/.restore.info
fi
if [ -d $HOME/recyclebin ] && [ ! -e $HOME/.restore.info ]
then
touch $HOME/.restore.info
fi
### 4. Test Conditions
function test() {
for arg in $*
do
file=$arg
###No Filename Provided Error
if [ $# -eq 0 ]
then
echo "missing operand"
file="Error"
exit 1
###File Does Not Exist Error
elif [ ! -e $file ]
then
echo "Cannot delete $file: No such file exists"
file="Error"
exit 2
###Directory Name provided
elif [ -d $file ]
then
echo "Cannot delete $file : Not a file."
file="Error"
exit 3
###cannot delete any argument with recycle in it
elif [[ "${file}" =~ .*"recycle".* ]]
then
echo "Attempting to delete recycle – operation aborted"
file="Error"
exit 4
fi
processRequest
done
}
processRequest(){
echo "Entered processRequest"
if [ $noChoice = true ]
then
recycle
elif [ $iOption = true ] && [ $vOption = true ]
then
read -p "recycle: remove file '$file' ? [y/n] " response
case $response in
[yY]*)
recycle
echo "recycle: '$file' is removed";;
*)
continue ;;
esac
elif [ $iOption = true ]
then
read -p "recycle: remove file '$file' ? [y/n] " response
case $response in
[yY]*)
recycle
echo "recycle: '$file' is removed";;
*)
continue ;;
esac
elif [ $vOption = true ]
then
recycle
echo "removed '$file' to the Recycle Bin"
fi
}
### Assigning the values of flename, absolute path and inode to variable
### name, absolute_path and inode before sending it to recyclebin folder
recycle() {
# If no errors mv the file to the recyclebin folder and add to .restore.info file.
if [ $file != "Error" ] ; then
name=$(basename ${file}) #bcz file can be entered with full path
path_cropped=$(readlink -e ${i} | cut -d"/" -f6-)
path=$(dirname $(readlink -e ${i} | cut -d"/" -f6-))
absolute_path="${HOME}/${path_cropped}"
inode=$(stat -c '%i' ${file})
filename=$name"_"$inode
echo $newfilename:$fixedPath >> $HOME/.restore.info
mv $file $recyclepath/$newfilename
fi
}
###--------------------Starts from here after checking dir if exists or not--------------------------------------
###Declaring variables which further fulfills condition to act as i, v, r commands
###as i = iOption; v = vOption; no command = noChoice and recycle files recursively
### = r or R
noChoice=true
iOption=false
vOption=false
removeFolder=false
while getopts ivrRvi opt
do
case $opt in
iv)
iOption=true
vOption=true
noChoice=false
break;;
vi)
iOption=true
vOption=true
noChoice=false
break;;
i)
iOption=true
noChoice=false
break;;
v)
vOption=true
noChoice=false
break;;
r)
removeFolder=true
break;;
R)
removeFolder=true
break;;
esac
done
shift $(($OPTIND - 1))
### CAlling the test function to test all the mentioned conditioned inside the test function
test
--------------------------------------------------------------------------
``` ```````````````````````````````````````````````````````````````
**Solved code**
``` ```````````````````````````````````````````````````````````````
#!bin/bash
### 2. creating directory ~/recyclebin in home if not present
if [[ ! -d $HOME/recyclebin ]]
then
mkdir $HOME/recyclebin
#touch $HOME/.restore.info
fi
### Creating .restore.info file if file is not yet present in
### home directory
if [ -d $HOME/recyclebin ] && [ ! -e $HOME/.restore.info ]
then
touch $HOME/.restore.info
fi
if [ $# -eq 0 ]
then
echo "recycle: missing operand"
exit 1
fi
### 4. Test Conditions to check
testCondition() {
for arg in "$#"
do
file=$arg
###File Does Not Exist Error
if [ ! -e "$file" ]
then
echo "recycle: Cannot delete $file: No such file exists"
file="Error"
exit 2
###Directory Name provided
elif [ -d $file ]
then
echo "recycle: Cannot delete $file : Is a directory."
file="Error"
exit 3
###cannot delete any argument with recycle in it
elif [[ "${file}" =~ .*"recycle".* ]]
then
echo "recycle: Attempting to delete – operation aborted"
file="Error"
exit 4
fi
processRequest $file
done
}
processRequest(){
if [[ "$noChoice" = true ]]
then
recycle $file
elif [ "$iOption" = true ] && [ "$vOption" = true ]
then
echo "recycle: remove file '$file' ? [y/n] "
read response
case $response in
[yY]*)
recycle $file
echo "recycle: '$file' is removed";;
*)
continue ;;
esac
elif [ "$iOption" = true ]
then
read -p "recycle: remove file '$file' ? [y/n] " response
case $response in
[yY]*)
recycle $file
echo "recycle: '$file' is removed";;
*)
continue ;;
esac
elif [ "$vOption" = true ]
then
recycle $file
echo "removed '$file' to the Recycle Bin"
fi
}
### Assigning the values of flename, absolute path and inode to variable
### name, absolute_path and inode before sending it to recyclebin folder
recycle() {
# If no errors mv the file to the recyclebin folder and add to .restore.info file.
if [[ ! $file == "Error" ]]
then
name=$(basename $file) #bcz file can be entered with full path
path_cropped=$(readlink -e $file | cut -d"/" -f6-)
absolute_path="${HOME}/${path_cropped}"
inode=$(stat -c '%i' $file)
filename=$name"_"$inode
echo $filename:$absolute_path >> $HOME/.restore.info # saving filename:path/to/file in .restore.info
mv $file $HOME/recyclebin/$filename # movinf file as filename_inode to recyclebin
fi
}
recFolder() {
for arg in $*
do
dirPath=$(readlink -e "$arg")
if [ -d "$dirPath" ] # check if the current argument IS a directory
then
if [[ $(ls "$dirPath" | wc -l) -eq 0 ]] #check to see if current directory is empty
then
rmdir $dirPath
else #if not an empty directory
findCurPathList=$(find $dirPath) # to find all the subdirectories and files list inside directory
for file in $findCurPathList
do
if [[ -f "$file" ]] #if it is a file
then
processRequest "$file"
fi
done
#-----------------------------------------------Now in previous loop, once all the files are removed and saved in
#recyclebinfolder and in .recycle.info file. Now delete the
#empty subdirectories in second loop
for args1 in $findCurPathList
do
if [[ -d $args1 ]]
then
if [[ $(ls $args1 | wc -l) -eq 0 ]]
then
rmdir $args1
fi
fi
done
#if [[ $(ls "$arg" | wc -l) -eq 0 ]] #check to see if current directory is empty
#then
# rmdir $dirPath
#fi
fi
else # if NOT a directory then this executes
echo "recycle: not a directory"
fi
done
}
###--------------------Starts from here, after checking dir if exists or not--------------------------------------
###Declaring variables which further fulfills condition to act as i, v, r commands
###as i = iOption; v = vOption; no command = noChoice and recycle files recursively
### = r or R
noChoice=true
iOption=false
vOption=false
removeFolder=false
while getopts ivrR opt
do
case $opt in
i)
iOption=true
noChoice=false;;
v)
vOption=true
noChoice=false;;
r)
removeFolder=true;;
R)
removeFolder=true;;
*)
echo "recycle: invalid input"
exit 1;;
esac
done
shift $(($OPTIND - 1))
### Now checking if -r or -R is passed as an argument and the passed in file argument
### is either directory or existing file to continue
if [[ "$removeFolder" == true ]]
then
for arg in "$#"
do
inputArg=$arg
if [[ -d $inputArg || -e $inputArg ]] # if the user pass -r request but the argument could either be
#a directory o a file not directory
then
argList=$(find "$inputArg")
recFolder "$argList"
else
echo "recycle: $inputArg does not exist!"
fi
done
else
### CAlling the test function to test all the mentioned conditioned inside the test function
testCondition "$#"
fi
I'm trying to add options to my little safe delete script. For example, I can do ./sdell -s 100 and it will delete files with size above 100 kbs. Anyway, I'm having problems with my safe guard function.
#!/bin/bash
#Purpose = Safe delete
#Created on 20-03-2018
#Version 0.8
#jesus,i'm dumb
#START
##Constants##
dir="/home/cunha/LIXO"
#check to see if the imputs are a files#
for input in "$#"; do
if ! [ -e "$input" ]; then
echo "Input is NOT a file!"
exit 1
fi
done
###main###
case $1 in
-r) echo "test option -r"
;;
*) if [[ -f "$dir/$fwe.tar.bz2" ]]; then
echo "File already exists."
if [[ "$file" -nt "$2" ]]; then
echo "Removing older file." && rm "$dir"/"$fwe.tar.bz2" && tar -czPf "$fwe.tar.bz2" "$(pwd)" && mv "$fwe.tar.bz2" "$d$
fi
else
echo "Ziping it and moving." && tar -czPf "$fwe.tar.bz2" "$(pwd)" && mv "$fwe.tar.bz2" "$dir"
fi
done
;;
esac
The problem is when I call ./sdell -r file1.txt, it says that the input is not a file.
Here is the script without the case, 100% working before having options.
#!/bin/bash
#Purpose = Safe delete
#Created on 20-03-2018
#Version .7
#START
##Constants##
dir="/home/cunha/LIXO"
#check to see if the imputs are a files#
for input in "$#"; do
if ! [ -e "$input" ]; then
echo "Input is NOT a file!"
exit 0
fi
done
###main###
##Cycle FOR so the script accepts multiple file inputs##
for file in "$#"; do
fwe="${file%.*}"
#IF the input file already exist in LIXO#
if [[ -f "$dir/$fwe.tar.bz2" ]]; then
echo "File already exists."
#IF the input file is newer than the file thats already in LIXO#
if [[ "$file" -nt "$2" ]]; then
echo "Removing older file." && rm "$dir"/"$fwe.tar.bz2" && tar -czPf "$fwe.tar.bz2" "$(pwd)" && mv "$fwe.tar.bz2" "$d$
fi
else
echo "Ziping it and moving." && tar -czPf "$fwe.tar.bz2" "$(pwd)" && mv "$fwe.tar.bz2" "$dir"
fi
done
The message you are seeing is unrelated to the case..esac, construct, it is printed by this section:
for input in "$#"; do
if ! [ -e "$input" ]; then
echo "Input is NOT a file!"
exit 1
fi
done
which expands all command-line parameters ($#), including the "-r", and exits the script because "-r" is not a file. The case..esac is never reached. You can run your script with
bash -x file.sh -r test
so that you can see exactly which lines are being executed.
The snippet below probably does what you want, processing all arguments sequentially:
#!/bin/bash
while [ ! -z $1 ]; do
case $1 in
-r) echo "option R"
;;
-f) echo "option F"
;;
*) if [ -f $1 ]; then echo "$1 is a file." ; fi
;;
esac
shift
done
Consider checking if -r has been passed before trying other options and use shift if it was:
#!/usr/bin/env sh
dir="/home/cunha/LIXO"
case $1 in
-r) echo "test option -r"
shift
;;
esac
#check to see if the imputs are a files#
for input in "$#"; do
echo current input: "$input"
if ! [ -e "$input" ]; then
echo "Input $input is NOT a file!"
exit 1
fi
done
if [[ -f "$dir/$fwe.tar.bz2" ]]; then
echo "File already exists."
if [[ "$file" -nt "$2" ]]; then
echo "Removing older file..."
# add stuff
fi
else
echo "Ziping it and moving."
# add stuff
fi
I need to make a script that creates soft/symbolic links, but should also detect if links already exist in the '~/linkedfiles' directory, but the problem is that $file also contains sub directories. ($file will look like this: '~/realfiles/files/file23.gz', but I need 'file23.gz' only.) So my question is, how do I remove the sub directories in $file?
Here is some code as an example:
for file in ~/realfiles/files/*.gz
do
echo "Linking file: $file"
ln -s $file ~/linkedfiles
if [ $? -ne 0 ]; then
echo "[FAIL] Linking of $file failed!"
else
echo "[SUCCESS] $file successfully linked."
fi
done
It appears that you want the base name of the path. There are two ways to do that — the classic reliable way is with the basename command, and the modern not-always-reliable way is with a shell parameter expansion.
for file in ~/realfiles/files/*.gz
do
echo "Linking file: $file"
ln -s "$file" "~/linkedfiles/$(basename "$file")"
if [ $? -ne 0 ]
then echo "[FAIL] Linking of $file failed!"
else echo "[SUCCESS] $file successfully linked."
fi
done
Or:
for file in ~/realfiles/files/*.gz
do
echo "Linking file: $file"
ln -s "$file" "~/linkedfiles/${file##*/}"
if [ $? -ne 0 ]
then echo "[FAIL] Linking of $file failed!"
else echo "[SUCCESS] $file successfully linked."
fi
done
In both scripts, the file ~/realfiles/files/file23.gz will be linked to ~/linkedfiles/file23.gz, which is what I think you are after (though there is room to improve the clarity of the question, such as by citing the desired result for the sample file name).
Slight modification of original script would do
for filename in ~/realfiles/files/*.gz
do
echo "Linking file: $file"
[[ -h "~/linkedfiles/${var##*/}" ]] && continue
ln -s "$filename" ~/linkedfiles/
if [ $? -ne 0 ]
then
echo "[FAIL] Linking of $filename failed!"
else
echo "[SUCCESS] $filename successfully linked."
fi
done
Notes
The -h option with if [ checks ] if the file is a symbolic link
${var##*/} gives you the base name. Check [ parameter expansion ].
targetdir="$HOME/linkedfiles"
for filename in $HOME/realfiles/files/*.gz; do
# if filename is a regular file then ...
if [[ -f "${filename}" ]]; then
# if softlink does not exist in target then link it
if [[ ! -h "${targetdir}/${filename##*/}" ]]; then
echo "Linking ${filename}"
ln -s "${filename}" "${targetdir}"
(( $? == 0 )) && echo 'Link created' || echo 'Create link fails'
else
echo "Skipping because ${filename##*/} exists in ${targetdir}"
fi
fi
done
I am having a problem with a bash script that I am working on, I am practically new to Bash Scripting and been working on this problem for hours and cant figure out what the problem could be.
When I run the script this are the errors I get:
backupscripts.sh: line 55: conditional binary operator expected
backupscripts.sh: line 55: syntax error near `!=0'
backupscripts.sh: line 55: ` if [[ $? !=0 ]]; then echo "Problems Copying Backup File to Backup Host;" fi'
Hope you can help me out pointing me out what the problem could be, thnx.
Here is the script:
#!/bin/bash
BACKUPDIR=~/backup
SCRIPTDIR=~/arespaldar
BACKUPFILE=/backup.$(date +%F).bz2
BACKUPHOST=199.21.112.70
COUNT=$(ls $BACKUPDIR | wc -l)
TRESHOLD=7
function checkbackupdir() {
if [ ! -e $BACKUPDIR ]
then
echo "Creating Backup Directory because it doesn\'t exist !"
mkdir ~/backup
COUNT=0
# exit 0
else
COUNT=$(ls $BACKUPDIR | wc -l)
fi
}
function backup() {
if [[ $COUNT -le $THRESHOLD ]]
then
tar -cjvf $BACKUPDIR/$BACKUPFILE $SCRIPTDIR
if [[ $? -ne 0 ]]; then echo "Poblems Creating Backup File;" fi
scp $BACKUPDIR/$BACKUPFILE $BACKUPHOST:
if [[ $? !=0 ]]; then echo "Problems Copying Backup File to Backup Host;" fi
}
checkbackupdir
backup
I have made changes suggested and now when I run the script I get this error:
backupscripts.sh: line 34: syntax error near unexpected token ('
backupscripts.sh: line 34:foo checkbackupdir () {'
This is line 34
foo checkbackupdir () {
And here is the full Script with changes done to it:
#!/bin/bash
# Author: Chris Navarrete
# Date: 16.06.2013
# Purpose: Used to backup files and/or directories locally and store remotely
# THIS LINES BELOW ARE THE VARIABLES
BACKUPDIR=~/backup
SCRIPTDIR=~/arespaldar
BACKUPFILE=/backup.$(date +%F).bz2
BACKUPHOST=199.21.112.70
COUNT=$(ls $BACKUPDIR | wc -l)
TRESHOLD=7
foo checkbackupdir () {
if [ ! -e "$BACKUPDIR" ]
then
echo "Creating Backup Directory because it doesn\'t exist !"
mkdir ~/backup
COUNT=0
# exit 0
else
COUNT=$(ls "$BACKUPDIR" | wc -l)
fi
}
foo backup () {
if [[ "$COUNT" -le "$THRESHOLD" ]]
then
tar -cjvf "$BACKUPDIR"/"$BACKUPFILE" "$SCRIPTDIR"
if [[ $? -ne 0 ]]; then echo "Poblems Creating Backup File;" fi
scp "$BACKUPDIR"/"$BACKUPFILE" "$BACKUPHOST":
if [[ $? -ne 0 ]]; then echo "Problems Copying Backup File to Backup Host;" fi
fi
}
checkbackupdir
backup
#END
Any ideas on what could be still causing this error ?
Thank you for the help guys.
replace
if [[ $? !=0 ]];
with
if [[ $? != 0 ]];
the missing space is causing the issue.
In bash "-ne" should be used for testing integer equality. Use line 53 as an example, looks like that is right.
Use "man test" on the command line to see all the options for conditional tests in a batch script. For integer comparison, it says:
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
My mnemonic is: for number comparison use the string test operators (ne, eq, gt), for string comparisons, use what you would use for numbers in other languages ("=" and "!'"). Basically it's opposite of what you (I) expect.