Shell Script - Make directory if it doesn't exist - shell

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

Related

Check if folder based on variables exists

I'm creating a bash script, but it does not seem to check if a folder exists, when it's based on variables. Although the folder does exists, when I cd into it.
#!/usr/bin/env bash
VAR1="/Users/nameuserhere/Desktop/";
VAR2=`date "+%Y-%m-%d"`;
VAR3="$VAR1$VAR2";
echo "folder path: $VAR3";
if [[ -f "$VAR3" ]]
then
echo "this/not does exists"
else
echo "this/not does not exist"
fi
Use -d, as -f check if it's a file:
-f FILE True if file exists and is a regular file

How do I combine an "if" and a "while loop" statement together?

New to shell scripting and I want to test to see if the variables I created are valid directories and if not send the user into a while loop to enter the directory and only allow exit when a valid directory is entered.
So far this is what my script looks like:
~/bin/bash
source_dir="$1"
dest_dir="$2"
mkdir /#HOME/$source_dir
mkdir /#HOME$dest_dir
if [ -d "$source_dir" ]
then
echo "$source_dir is a valid directory"
fi
while [[ ! -d "$source_dir" ]]
do
echo "Please enter a valid directory"
read source_dir
done
Is there any way to combine these into a single statement?
The while code will never execute if the directory is valid. Therefore just move the echo "$source_dir is a valid directory" after the loop:
#!/bin/bash
source_dir="$1"
dest_dir="$2"
mkdir "$HOME/$source_dir"
mkdir "$HOME/$dest_dir"
until [[ -d "$source_dir" ]]
do
read -p "Please enter a valid directory" source_dir
done
echo "$source_dir is a valid directory"
Notes:
a few code typos were fixed, e.g. /#HOME$dest_dir should be "$HOME/$dest_dir".
any while ! can be shortened to until.
The above code lacks a few things:
It tries create a new dir, then if that fails, has the user enter an already existing directory. It might be better to let the user create a new directory, but only if it doesn't already exist.
It would be better to check if $dest_dir exists.
Here's a more thorough approach using a shell function:
#!/bin/bash
untilmkdir ()
{
d="$1";
until mkdir "$d" ; do
read -p "Please enter a valid directory: " d
[ -d "$d" ] && break
done;
echo "$d is a valid directory" 1>&2
echo "$d"
}
source_dir=$(untilmkdir "$HOME/$1")
dest_dir=$(untilmkdir "$HOME/$2")
Notes:
The prompts in untilmkdir are printed to stderr.
The name of whatever directory untilmkdir creates is printed to stdout.
Having untilmkdir print to both stderr and stdout allows storing the successfully created name to a variable.

Space in directory name crashing .sh - use "usebackq"?

dir1='/d/Dropbox/PhD/Experimental Design/APS/Processed_and_Graphed/InvariantQ'
echo $dir1
for f in A*.xlsx
do
str2=${f%?????}
if [[ ! -d $dir1/$str2 ]]; then
mkdir $dir1/$str2
else
echo "Directory" $dir1/$str2 "already exists, directory not created"
fi
if [[ ! -f $dir1/$str2/$f ]]; then
mv -v $f $dir1/$str2
else
echo "File" $dir1/$str2/$f "already exists, file not copied"
fi
done
I'm trying to get the following script to run, however when it attempts to mkdir $dir1/$str2, it creates:
/d/Dropbox/PhD/Experimental
and returns back the error:
create directory '/d/Dropbox/PhD/Experimental': file exists
create directory 'Design/APS/Processed_and_Graphed/InvariantQ': no such file or directory
I've tried coding the directory name with double quotations, or a '\' in front of the space in 'Experimental Design', but neither method seems to work... It seems this can be achieved in batch files using "usebackq" -is there a way to do this in GitBash for windows? If so, where in my code would it be applied?
Also, is anyone aware as to why testing a statement here using "[[" works, whereas a single "[" doesn't?
Quote your variables to prevent word splitting on the expansion.
dir1='/d/Dropbox/PhD/Experimental Design/APS/Processed_and_Graphed/InvariantQ'
echo "$dir1"
for f in A*.xlsx
do
str2=${f%?????}
if [[ ! -d $dir1/$str2 ]]; then
mkdir "$dir1/$str2"
else
echo "Directory $dir1/$str2 already exists, directory not created"
fi
if [[ ! -f $dir1/$str2/$f ]]; then
mv -v "$f" "$dir1/$str2"
else
echo "File $dir1/$str2/$f already exists, file not copied"
fi
done
It works with [[ because this is shell syntax, not an ordinary command. It recognizes variables specially and doesn't do work splitting on them. This is the same reason that it allows you to use operators like < without quoting them.

Issue in Bash script

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"

Bash: If statement nested in for loop

I am writing a simple script to check if an entered directory path exists. This is what I have
echo "Please specify complete directory path"
read file_path
for file in $file_path; do
if [[ -d "$file" ]]; then
echo "$file is a directory"
break
else
echo "$file is not a directory, please try again."
fi
done
What I need is if it is not a directory to go back and ask for the file path again.
Thanks.
How about this?
echo "Please specify complete directory path"
while read file; do
if [[ -d "$file" ]]; then
echo "$file is a directory"
break
fi
echo "$file is not a directory, please try again."
done
No need to split the path into its parts, testing the entire path with -d will tell you whether or not it is a directory. You need to put the entire test into a while loop until the user gets it right:
#/bin/sh
set -e
file_path=''
while [ ! -d "$file_path" ]
do
echo "Please specify complete directory path"
read file_path
if [ ! -d "$file_path" ]
then
echo "$file_path is not a directory, please try again."
fi
done
I can use it like this
$ sh /tmp/test.sh
Please specify complete directory path
foobar
foobar is not a directory, please try again.
Please specify complete directory path
/var/www

Resources