This is my code:
#!/bin/bash
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
else if [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
my error: can anyone please help me i do not know what to do? I do not know where I am making mistake?
./script.sh: line 17: syntax error: unexpected end of file
Use elif instead of else if.
Syntax of if in bash:
if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
Instead of a single if statement with an elif clause, you nested a second if statement in the else clause of the first, but only terminated the second one. Your code, reformatted to highlight the issue, is
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
else
if [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
Notice the lack of a second fi which would terminate the outer if statement.
Using elif, your code becomes
if [[ -z $1 ]]; then
echo "No arguments passed: valid usage is script.sh filename"
elif [[ ! -f "$1" ]]; then
echo "file does not exists"
else
for i in {558..2005};
do
if [[ ! -d "/abc" ]]; then
mkdir /abc
fi
mkdir /abc/xyz$i
cp $1 /abc/xyz$i/$1
done
fi
The elif clause doesn't require a closing fi; it is implicitly terminated by the following else clause.
Related
I want to match a condition in bash containing "whitespaces" and "OR" condition within strings. I am unable to do as i am new to shell scripting, please help as it going to else loop where it is matching ${myarrlin[1]} . I am getting "Centrify is disabled" but i want the condition to be true here. Here is my code :
FILE_CENT="/etc/nsswitch.conf"
OS=`uname`
if [[ $OS = 'Linux' ]]; then
if [[ -e $FILE_CENT ]]; then
echo "nsswitch.conf found, Proceeding further..."
while read -r LINE
do
if [[ $LINE =~ ^passwd ]]; then
myarrlin=($LINE)
if [[ ${myarrlin[1]} =~ ^(centrify)|(centrifydc)[[:space:]]* || ${myarrlin[1]} =~ [[:space:]]+(centrify)|(centrifydc)[[:space:]]* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT
else
echo "nsswitch.conf does not exist in $OS, cannot fetch CENTRIFY information!"
fi
fi
nsswitch.conf >>>
passwd: centrify files
or
passwd: centrifydc files
or
passwd: files centrify
or
passwd: files centrifydc
Why are you doing this: myarrlin=($LINE) ?
If you just want to know if the line contains centrify:
while read -r LINE
do
if [[ ${LINE} =~ ^passwd ]]; then
if [[ ${LINE} == *"centrify"* ]]; then
echo "Centrify is enabled"
else
echo "Centrify is disabled"
fi
fi
done < $FILE_CENT
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´m trying to make a script which takes a single command-line argument. Then it looks on the argument and if its a directory name, it just prints that this directory exists. If its a file name, it prints out the file exists. Otherwise, it tries to create a directory with this name and tests whether it was successful and reports this on the standard output.
my code is:
while read argument; do
if [ $argument -d ]; then
echo "Directory exists"
elif [ $argument -e ]
echo "File exists"
else
mkdir $argument
if [ $argument -d]; then
echo "Directory was created"
else
echo "Error while creating the directory"
fi
fi
done
Then I run the code ./file_name.sh argument. If I run the code like this, I get an error on line 8, which is just "else". While is probably not necessary here, it was the first option how to accept an argument from the command line that came to my mind.
As you mentioned, you need single command line argument, So no need to loop
#!/bin/bash
if [[ -z "$1" ]]; then
echo "Help : You have to pass one argument"
exit 0
fi
if [[ -d "$1" ]]; then
echo "Directory exists"
elif [[ -f "$1" ]]; then
echo "File exists"
else
mkdir "$1"
if [ -d "$1" ]; then
echo "Directory was created"
else
echo "Error while creating the directory"
fi
fi
if [ -d $1 ]; then
echo "Directory exists"
elif [ -e $1 ]; then
echo "File exists"
else
mkdir $1
if [ -d $1 ]; then
echo "Directory was created"
else
echo "Error while creating the directory"
fi
fi
I made up this solution thanks to the links provided, thank you.
I am trying to write a simple program that checks if a given filename refers to a directory. But I keep getting an error saying that "bad interpreter: no such file or directory" when I run ./isdir.sh (This is the name of the script).
here is my code:
#!bin/sh
if [[ $# -ne 1 ]];then
echo "Usage: $0 dir"
exit 1
fi
dir="$1"
dirname = "$1"
if [[ ! -d "$dir" ]]; then
echo "Error: directory $dir not found."
exit 2
fi
if [[ -d "$dirname" ]]; then
echo "$dirname is a directory."
exit 3
ALSO, IMPORTANT QUESTION:
How do I handle input values that contain spaces in them?
You could do this:
#!/bin/bash
if [[ $# -ne 1 ]]; then
echo "Usage: $0 dir"
exit 2
fi
dir="$1"
rc=1
if [[ -d "$dir" ]]; then
# it is a directory
rc=0
elif [[ -e "$dir" ]]; then
echo "Error: '$dir' is not a directory"
else
echo "Error: directory '$dir' does not exist"
fi
exit "$rc"
Don't need the dirname variable.
The script is safe for directories that have white spaces or wild cards in their name as we have enclosed the variable in double quotes.
Exit code of 2 is a Unix standard for invalid argument error; exit 1 is all other errors. However, you can change the exit codes as per your need.
See this related post for more perspectives around this problem: Check if a directory exists in a shell script
I need to create one file list for below files:
APPLE_001
APPLE_002
BBB_004
APPLE_003
I need to create file_list only for
APPLE_001
APPLE_002
APPLE_003
Thanks,
Ipsita
Your specifications are not that narrow, but here a bash script that match your request :
#!/bin/bash
if [[ $# < 2 ]]
then
echo "[ERROR] this script expects two arguments, input file and output file" >&2
exit 1
fi
input_file=$1
output_file=$2
if [[ ! -f $input_file ]]
then
echo "[ERROR] your input file '$input_file' is missing" >&2
exit 1
fi
if [[ -f $output_file ]]
then
echo "[ERROR] your output file '$ouput_file' already exists please move it away" >&2
exit 1
fi
while read LINE
do
if [[ $LINE =~ APPLE_[0-9]+ ]]
then
echo $LINE >> $output_file
else
echo "'$LINE' does not match expected pattern, skip it"
fi
done < $input_file
if [[ -f $ouput_file ]]
then
echo "'$output_file' generated."
else
echo "[WARNING] no pattern found in '$input_file' no file generated"
fi
make it executable ( chmod +x ./list_starting_with.sh )
run it with ./list_starting_with.sh file_in.txt file_out.txt