Issue in Bash script - bash

I have a bash script which creates a directory if not already present and moves all the files to the newly created directory.
The bash script I have is returning is not working and the error is receive is
./move.sh: line 5: =/data/student/stud_done_11-11-2013: No such file or directory
already present
mv: missing destination file operand after `a.xml'
Try `mv --help' for more information.
The bash script is:
# Back up
if [ $# = 1 ]
then
$dir="/data/student/stud_done_$1"
echo $dir
if [ ! -d $dir ]; then
mkdir $dir
else
echo "already present"
fi
cd /data/student/stud_ready
mv * $dir
else
echo "No files to move"
fi
I invoke the script as follows:
./move.sh "11-11-2013"
What is the error in my script.

Here (on line 5)...
$dir="/data/student/stud_done_$1"
You meant...
dir="/data/student/stud_done_$1"

Related

Check if file exist relative to current script (one level up)

How to check/get file path relative to current script?
Script is running from ..../app/scripts/dev.sh
File to check from ..../app/dist/file.js
dir="${BASH_SOURCE%/*}../dist/backend.js"
if [ -f ${dir} ]; then
echo "file exists. ${dir}"
else
echo "file does not exist. ${dir}"
fi
There are three problems in your script.
To store the output of a command in a variable, use $(), not ${}.
[ -f "$dir" ] checks if $dir is a a file, which will never happen, because dirname outputs a directory.
Your script can be executed from any other working directory as well. Just because the script is stored in ···/app/scripts/ does not mean it will always run from there.
Try
file=$(dirname "$BASH_SOURCE")/../dist/file.js
if [ -f "$file" ]; then
echo "file exists."
else
echo "file does not exist."
fi

Zip I/O error: No such file or directory in bash script

I've been writing some code to (mostly) automate password protecting and compressing/archiving folders and files. However, the code seems to hate me.
I've run it line by line, and it always chokes on the zip command, even when the $file and $source are correct and valid.
Any ideas?
Here's the source code:
#!/bin/bash
echo "Drag in the source file"
read source
echo
echo "Drag in the destination file, or press enter to select the Desktop"
read destination
echo
if [ -z "$destination" ]
then destination="$PWD/Desktop"
echo "Destination is set to the desktop"
fi
echo "Type the name of the file to make"
read file
if [ -z "$file" ]
then file="archive"
echo "File name set to archive.zip"
fi
file="${destination}/${file}"
if [ -d $"source" ]
then zip -erj "$file" "$destination"
else zip -ej "$file" "$destination"
fi
There are a couple of problems in your code:
if [ -z "$destination" ]
then destination="$PWD/Desktop"
echo "Destination is set to the desktop"
fi
$PWD is the current working directory. It is your home directory when you open a Terminal but it changes everytime you run cd.
The Desktop directory is $HOME/Desktop.
If you don't run the script from your home directory, most probably $PWD/Desktop doesn't exist and this is a cause for errors; zip doesn't attempt to create the destination directory for the archive you ask it to build. If the directory doesn't already exist it displays an error message and exits.
Another problem is on the invocation of zip:
if [ -d $"source" ]
then zip -erj "$file" "$destination"
else zip -ej "$file" "$destination"
fi
You probably want to archive the file $source or the files in the $source directory (if it is a directory) but you mistakenly put $destination as the file/directory to archive in the zip command line.
if [ -d $"source" ] -- it should be "$source", otherwise the quote are useless and if $source contains spaces the script will exit with a syntax error.
One last thing: zip doesn't mind receiving -r in the command line when it is asked to archive only one file. You can replace the entire if/else block above with a single command:
zip -erj "$file" "$source"

Linux shell script to copy and rename multiple files

I have this snippet:
#!/bin/bash
parent=/parent
newfolder=/newfolder
mkdir "$newfolder"
for folder in "$parent"/*; do
if [[ -d $folder ]]; then
foldername="${folder##*/}"
for file in "$parent"/"$foldername"/*; do
filename="${file##*/}"
newfilename="$foldername"_"$filename"
cp "$file" "$newfolder"/"$newfilename"
done
fi
done
I do need to turn it around in a way that the copied files would be named after the folder they are being moved to (e.g. moving to the /root/Case22 files would be renamed to case22_1.jpg, case22_2.docx, case22_3.JPG etc). The files would be copied from USB and both destination and source directries would be entered by the user. I have written everything else and it works apart from actual renaming and thought I could adapt this snippet.
thanks
p.s. the snippet is written by Jahid and found on stackoverflow
you can try something like this;
#!/bin/bash
parent=/root
a=1
for file in $parent/Case22*; do
filename="${file%.*}"
extension="${file##*.}"
newfilename=$(printf "$filename"_"$a"."$extension")
mv -- "$file" "$newfilename"
let a=a+1
done
Thanks for the help. I have found the solution and thought I might post it here in case someone else will be looking at this.
As the title suggests I needed a Linux shell script to copy and rename multiple files keeping original directory tree (the file source and archive locations would be specified by the user of the script). Here is the code that I came up with after few days research of different sources (it includes a trap so only one instance of script would be running at a time):
lockdir=/var/tmp/mylock #directory for lock file creation
pidfile=/var/tmp/mylock/pid #directory to get the process ID number
if ( mkdir ${lockdir} ) 2> /dev/null; then #main argument to create lock file
echo $$ > $pidfile #if successful script will proceed, otherwise it will skip to the else part of the statement at the end of the script
trap 'rm -rf "$lockdir"; exit $?' INT TERM EXIT #trap to capture reasons of script termination and removal of the lock file so it could be launched again
#start of the main script body, part of successful "if" statement
# read entry_for_testing_only #request for user entry to keep script running and try to run another script instance
findir="$2/$(basename "$1")" #variable that defines final directory to which files from USB will be copied
if [ ! -d "$1" ]; then #testing if first directory entry is a valid directory’’
echo "$1" "is not a directory"
echo ""
exit
else
if [ ! -d "$2" ]; then #testing if second entry is a valid directory
echo "archive directory non existant"
exit
else
if [ -d "$findir" ] && [ "$(ls -A "$findir")" ]; then #testing if second entry directory contains the same name folders and if the folders are empty - to avoid file overwriting
echo "such folder already there and it's not empty"
exit
else
if [ ! -d "$findir" ] ; then #last archive directory argument to create final archive directory
mkdir "$findir"
else true
fi
fi
fi
fi
rsync -a "$1"/ "$findir" #command to copy all files from the source to the archive retaining the directory tree
moved_files="$(find "$findir" -type f)" #variable that finds all files that have been copied to the archive directory
for file in $moved_files; do #start of the loop that renames copied files
counter="$((counter+1))" #incrementation variable
source_name="$(basename "$1")" #variable that captures the name of the source directory
new_name="$source_name"_"$counter" #variable that puts start of the file name and incrementation element together
if echo "$file" | grep "\." #argument that captures the extension of the file
then
extension="$(echo "$file" | cut -f2 -d. )"
else
extension=
fi
full_name="$new_name"."$extension" #variable that defines the final new name of the file
dir="$(dirname "${file}")" #variable that captures the directorry address of currently looped file
mv "$file" "$dir/$full_name" #move command to rename currently looped file with the final new name
done
#end of the main script body, unsuccessful "if" statement continues here
else
echo "Another instance of this script is already running. PID: $(cat $pidfile)"
fi

Shell Script - Make directory if it doesn't exist

I want to enter the name of a directory and check if it exists.
If it doesn't exist I want to create but I get the error mkdir: cannot create directory'./' File exists
My code says that the file exists even though it doesn't. What am I doing wrong?
echo "Enter directory name"
read dirname
if [[ ! -d "$dirname" ]]
then
if [ -L $dirname]
then
echo "File doesn't exist. Creating now"
mkdir ./$dirname
echo "File created"
else
echo "File exists"
fi
fi
if [ -L $dirname]
Look at the error message produced by this line: “[: missing `]'” or some such (depending on which shell you're using). You need a space inside the brackets. You also need double quotes around the variable expansion unless you use double brackets; you can either learn the rules, or use a simple rule: always use double quotes around variable substitution and command substitution — "$foo", "$(foo)".
if [ -L "$dirname" ]
Then there's a logic error: you're creating the directory only if there is a symbolic link which does not point to a directory. You presumably meant to have a negation in there.
Don't forget that the directory might be created while your script is running, so it's possible that your check will show that the directory doesn't exist but the directory will exist when you try to create it. Never do “check then do”, always do “do and catch failure”.
The right way to create a directory if it doesn't exist is
mkdir -p -- "$dirname"
(The double quotes in case $dirname contains whitespace or globbing characters, the -- in case it starts with -.)
Try this code:
echo "Enter directory name"
read dirname
if [ ! -d "$dirname" ]
then
echo "File doesn't exist. Creating now"
mkdir ./$dirname
echo "File created"
else
echo "File exists"
fi
Output Log:
Chitta:~/cpp/shell$ ls
dir.sh
Chitta:~/cpp/shell$ sh dir.sh
Enter directory name
New1
File doesn't exist. Creating now
File created
chitta:~/cpp/shell$ ls
New1 dir.sh
Chitta:~/cpp/shell$ sh dir.sh
Enter directory name
New1
File exists
Chitta:~/cpp/shell$ sh dir.sh
Enter directory name
New2
File doesn't exist. Creating now
File created
Chitta:~/cpp/shell$ ls
New1 New2 dir.sh
try this: ls yourdir 2>/dev/null||mkdir yourdir, which is tiny and concise and fulfils your task.
read -p "Enter Directory Name: " dirname
if [[ ! -d "$dirname" ]]
then
if [[ ! -L $dirname ]]
then
echo "Directory doesn't exist. Creating now"
mkdir $dirname
echo "Directory created"
else
echo "Directory exists"
fi
fi

"Command not found" (simple bash script)

I need to write a basic program which would find the files which have odd (uneven) size in bytes in user specified directory and then rename them. I wrote a code but can't figure it out what's wrong with it since I have only just began to programm bash scripts... I have 3 files in my directory and here are the errors I'am getting for them:
./Untitled: line 18: AppIcon.icns: command not found
mv: cannot stat ‘AppIcon.icns’: No such file or directory
./Untitled: line 18: AssociatedVm.txt: command not found
mv: cannot stat ‘AssociatedVm.txt’: No such file or directory
./Untitled: line 18: Info.plist: command not found
mv: cannot stat ‘Info.plist’: No such file or directory
My script Code:
#!/bin/bash
n=0
echo “Specify directory”
read directory
if [ -d $directory ]; then
echo “Directory found”
else
echo “Directory not found”
exit 0
fi
for file in $( ls $directory );
do
fsize=$(stat "$directory/$file" -c %s)
if [ $((fsize%2))=1 ]; then
mv "$directory/$file" "$directory/$file.odd"
n=$((n + 1))
fi
done
echo ”Number of renamed files: $n ”
I think you meant
fsize=$(stat "$file" -c %s)
but you wrote
fsize=stat "$file" -c %s
Also, you need to use the absolute path($directory/$file) instead of $file alone if you are running the script from a directory which is not $directory.
Bash uses -eq for integer comparison, so you should also change
if [ $((fsize%2))=1 ]; then
to
if [ $((fsize%2)) -eq 1 ]; then
What is the -c %s for? I don't see a -c option in the stat man page. Did you mean -f? (EDIT: Ok I was looking at the Mac stat command (which is BSD). The stat in GNU version uses -c for format specification)

Resources