Bash script expecting then, when else is needed - bash

I am trying to run a shell script called graphhopper.sh in Ubuntu 12.04 which was given by a website. When I run it, terminal produces
: not found.sh: 2: graphhopper.sh:
graphhopper.sh: 39: graphhopper.sh: Syntax error: "else" unexpected (expecting "then")
The lines which start from 37 in the shell file are,
if [ ${OSM_FILE: -4} == ".pbf" ]; then
wget -O $OSM_FILE $LINK
else
# make sure aborting download does not result in loading corrupt osm file
TMP_OSM=temp.osm
wget -O - $LINK | bzip2 -d > $TMP_OSM
mv $TMP_OSM $OSM_FILE
fi
if [ ! -f "$OSM_FILE" ]; then
echo "ERROR couldn't download or extract OSM file $OSM_FILE ... exiting"
exit
fi
else
echo "## using existing osm file $OSM_FILE"
fi
This is the whole shell script.
#!/bin/bash
GH_HOME=$(dirname $0)
JAVA=$JAVA_HOME/bin/java
if [ "x$JAVA_HOME" = "x" ]; then
JAVA=java
fi
vers=`$JAVA -version 2>&1 | grep "java version" | awk '{print $3}' | tr -d \"`
bit64=`$JAVA -version 2>&1 | grep "64-Bit"`
if [ "x$bit64" != "x" ]; then
vers="$vers (64bit)"
fi
echo "## using java $vers from $JAVA_HOME"
CONFIG=config.properties
if [ ! -f "config.properties" ]; then
cp config-example.properties $CONFIG
fi
ACTION=$1
FILE=$2
USAGE="./graphhopper.sh import|ui|test <your-osm-file>"
if [ "x$ACTION" = "x" ]; then
echo -e "## action $ACTION not found. try \n$USAGE"
fi
function ensureOsmXml {
if [ ! -s "$OSM_FILE" ]; then
echo "File not found '$OSM_FILE'. Press ENTER to get it from: $LINK"
echo "Press CTRL+C if you do not have enough disc space or you don't want to download several MB."
read -e
echo "## now downloading OSM file from $LINK and extracting to $OSM_FILE"
if [ ${OSM_FILE: -4} == ".pbf" ]; then
wget -O $OSM_FILE $LINK
else
# make sure aborting download does not result in loading corrupt osm file
TMP_OSM=temp.osm
wget -O - $LINK | bzip2 -d > $TMP_OSM
mv $TMP_OSM $OSM_FILE
fi
if [ ! -f "$OSM_FILE" ]; then
echo "ERROR couldn't download or extract OSM file $OSM_FILE ... exiting"
exit
# fi
else
echo "## using existing osm file $OSM_FILE"
fi
}
function ensureMaven {
# maven home existent?
if [ "x$MAVEN_HOME" = "x" ]; then
# not existent but probably is maven in the path?
MAVEN_HOME=`mvn -v | grep "Maven home" | cut -d' ' -f3`
if [ "x$MAVEN_HOME" = "x" ]; then
# try to detect previous downloaded version
MAVEN_HOME="$GH_HOME/maven"
if [ ! -f "$MAVEN_HOME/bin/mvn" ]; then
echo "No Maven found in the PATH. Now downloading+installing it to $MAVEN_HOME"
cd "$GH_HOME"
MVN_PACKAGE=apache-maven-3.0.5
wget -O maven.zip http://www.eu.apache.org/dist/maven/maven-3/3.0.5/binaries/$MVN_PACKAGE-bin.zip
unzip maven.zip
mv $MVN_PACKAGE maven
rm maven.zip
fi
fi
fi
}
function packageCoreJar {
if [ ! -f "$JAR" ]; then
echo "## now building graphhopper jar: $JAR"
echo "## using maven at $MAVEN_HOME"
#mvn clean
"$MAVEN_HOME/bin/mvn" -f "$GH_HOME/core/pom.xml" -DskipTests=true install assembly:single > /tmp/graphhopper-compile.log
returncode=$?
if [[ $returncode != 0 ]] ; then
echo "## compilation failed"
cat /tmp/graphhopper-compile.log
exit $returncode
fi
else
echo "## existing jar found $JAR"
fi
}
function prepareEclipse {
ensureMaven
packageCoreJar
cp core/target/graphhopper-*-android.jar android/libs/
}
## now handle actions which do not take an OSM file
if [ "x$ACTION" = "xclean" ]; then
rm -rf */target
exit
elif [ "x$ACTION" = "xeclipse" ]; then
prepareEclipse
exit
elif [ "x$ACTION" = "xandroid" ]; then
prepareEclipse
"$MAVEN_HOME/bin/mvn" -f "$GH_HOME/android/pom.xml" install android:deploy android:run
exit
fi
if [ "x$FILE" = "x" ]; then
echo -e "no file specified? try \n$USAGE"
exit
fi
# NAME = file without extension if any
NAME="${FILE%.*}"
if [ ${FILE: -4} == ".osm" ]; then
OSM_FILE=$FILE
elif [ ${FILE: -4} == ".pbf" ]; then
OSM_FILE=$FILE
elif [ ${FILE: -7} == ".osm.gz" ]; then
OSM_FILE=$FILE
else
# no end default to osm
OSM_FILE=$NAME.osm
fi
GRAPH=$NAME-gh
VERSION=`grep "<name>" -A 1 pom.xml | grep version | cut -d'>' -f2 | cut -d'<' -f1`
JAR=core/target/graphhopper-$VERSION-jar-with-dependencies.jar
# file without path (.osm.gz or osm.bz2 is also possible)
TMP=$(basename "$FILE")
TMP="${TMP%.*}"
TMP="${TMP%.*}"
if [ "x$TMP" = "xunterfranken" ]; then
LINK="http://download.geofabrik.de/openstreetmap/europe/germany/bayern/unterfranken.osm.bz2"
JAVA_OPTS="-XX:PermSize=60m -XX:MaxPermSize=60m -Xmx200m -Xms200m"
elif [ "x$TMP" = "xgermany" ]; then
LINK=http://download.geofabrik.de/openstreetmap/europe/germany.osm.bz2
# Info: for import we need a more memory than for just loading it
JAVA_OPTS="-XX:PermSize=60m -XX:MaxPermSize=60m -Xmx1600m -Xms1600m"
else
LINK=`echo $NAME | tr '_' '/'`
if [ ${FILE: -4} == ".osm" ]; then
LINK="http://download.geofabrik.de/$LINK-latest.osm.bz2"
else
LINK="http://download.geofabrik.de/$LINK-latest.osm.pbf"
fi
if [ "x$JAVA_OPTS" = "x" ]; then
JAVA_OPTS="-XX:PermSize=60m -XX:MaxPermSize=60m -Xmx1000m -Xms1000m"
fi
fi
ensureOsmXml
ensureMaven
packageCoreJar
echo "## now $ACTION. JAVA_OPTS=$JAVA_OPTS"
if [ "x$ACTION" = "xui" ] || [ "x$ACTION" = "xweb" ]; then
export MAVEN_OPTS="$MAVEN_OPTS $JAVA_OPTS"
"$MAVEN_HOME/bin/mvn" -f "$GH_HOME/web/pom.xml" -Dgraphhopper.config=$CONFIG \
-Dgraphhopper.osmreader.osm=$OSM_FILE -Djetty.reload=manual jetty:run
elif [ "x$ACTION" = "ximport" ]; then
"$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.GraphHopper printVersion=true config=$CONFIG \
graph.location="$GRAPH" \
osmreader.osm="$OSM_FILE"
elif [ "x$ACTION" = "xtest" ]; then
"$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.GraphHopper printVersion=true config=$CONFIG \
graph.location="$GRAPH" osmreader.osm="$OSM_FILE" prepare.chShortcuts=false \
graph.testIT=true
elif [ "x$ACTION" = "xmeasurement" ]; then
ARGS="graph.location=$GRAPH osmreader.osm=$OSM_FILE prepare.chShortcuts=fastest osmreader.acceptWay=CAR"
echo -e "\ncreate graph via $ARGS, $JAR"
START=$(date +%s)
"$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.GraphHopper $ARGS prepare.doPrepare=false
END=$(date +%s)
IMPORT_TIME=$(($END - $START))000
function startMeasurement {
COUNT=5000
ARGS="$ARGS prepare.doPrepare=true measurement.count=$COUNT measurement.location=$M_FILE_NAME graph.importTime=$IMPORT_TIME"
echo -e "\nperform measurement via $ARGS, $JAR"
"$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.util.Measurement $ARGS
}
# use all <last_commits> versions starting from HEAD
last_commits=$3
if [ "x$last_commits" = "x" ]; then
# use current version
"$MAVEN_HOME/bin/mvn" -f "$GH_HOME/core/pom.xml" -DskipTests clean install assembly:single
startMeasurement
exit
fi
commits=$(git rev-list HEAD -n $last_commits)
for commit in $commits; do
git checkout $commit -q
M_FILE_NAME=`git log -n 1 --pretty=oneline | grep -o "\ .*" | tr " ,;" "_"`
M_FILE_NAME="measurement$M_FILE_NAME.properties"
echo -e "\nusing commit $commit and $M_FILE_NAME"
"$MAVEN_HOME/bin/mvn" -f "$GH_HOME/core/pom.xml" -DskipTests clean install assembly:single
startMeasurement
done
fi

[Expanded from my comment...] The script file apparently has DOS-style line endings (i.e. carriage return followed by linefeed, instead of just linefeed). This confuses the shell greatly, since it sees the carriage return as part of the command. The giveaway is that first error message:
: not found.sh: 2: graphhopper.sh:
What's actually happened is it printed the error message "graphhopper.sh: 2: graphhopper.sh: ^M: not found" (where the ^M is actually a carriage return); when the terminal sees the ^M it goes back to the beginning of the line, and prints the end of the error message over top of the beginning.
One of the other effects this has is that the shell can't recognize keywords at the end of lines. When it sees a line like:
if [ ${OSM_FILE: -4} == ".pbf" ]; then^M
...it thinks then^M a regular command, not the end of the condition part of the if command, so it keeps looking for a then. But the else command seems to have some spaces at the end:
else ^M
...which means the shell does recognize the else keyword and get very confused about what it's doing in the middle of the condition part of the if.
So what can you do about it? There's almost certainly a command for it; I'm used to dos2unix, but apparently ubuntu doesn't have that, instead the "tofrodos" package includes the command fromdos (see here). Or, you can do it with perl:
perl -pi -e 's/\r//g' graphhopper.sh
Your text editor may also be able to save in unix (rather than DOS) format. Speaking of which, you should either switch your text editor to unix mode, or find a different text editor for scripting.

Remove the extra fi:
if [ ! -f "$OSM_FILE" ]; then
echo "ERROR couldn't download or extract OSM file $OSM_FILE ... exiting"
exit
# fi
else
echo "## using existing osm file $OSM_FILE"
fi

The variable OSM_FILE is not set to anything. This causes it to expand to a empty string, which causes the shell to think there are syntax errors in the if conditions.
Print out the value of OSM_FILE before use, and if it's empty, debug backwards.

Related

echo >> Gives an Error Saying the File Doesn't Exist

According to research, echo >> should create the file if it doesn't exist. (EDIT!! echoing to a file in the base terminal works. For some reason, it doesn't work in the .sh.) It works on the integrated "git bash" terminal, but not in MSYS2 MINGW. And one of my friends said that it gave an error in Fedora as well. My code is trying to detect if the cloned repo is the right version, and it will git pull origin main if it is outdated. Here is the code.
#!/bin/bash
NC='\033[0m' #Reset text color.
P='\033[0;35m' #Purple
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") #get the base directory of start.sh
cd $basedir
ver=$(sed '1!d' $(dirname $(pwd))/.version) #get local version
if ! [ -f .var/asked ]; then #this is in place so it only asks the below question once, ever.
if ! [ -f .var/vc ]; then #I don't know why this is here anymore
echo "Would you like ScratchLang to check its version every time you start it? [Y/N]"
read -sn 1 ff
if [ h$ff == hy ] || [ h$ff == hY ]; then
echo >>.var/vc "Don't remove this file please." #when start.sh detects this file, it will check for a new version.
fi
echo >>.var/asked "Don't remove."
fi
fi
if [ -f .var/vc ]; then
if ! [ h$1 == hnope ]; then
echo "Checking version..."
if [ -f .version ]; then
rm .version
fi
wget -q https://raw.githubusercontent.com/0K9090/ScratchLang/main/.version #get the .version file from github
utd=1
if ! [ "$ver" == "$(sed '1!d' .version)" ]; then #if local version doesn't match .version from github, then set utd to 0
utd=0
fi
if [ $utd == 0 ]; then #if utd = 0 then update
echo "Your version of ScratchLang ($ver) is outdated. The current version is $(sed '1!d' .version). Would you like to update? [Y/N]"
read -sn 1 hh
if [ h$hh == hy ] || [ h$hh == hY ]; then
git pull origin main
fi
exit
fi
rm .version
fi
fi

sed command in Solaris server

I have many javascript files in my solaris server which have some debug, print and trace statements which I want to comment. There are hundreds of file like this.
I have found a script to do this but the problem is the script is removing the urhk_b2k_printRepos statement instead of commenting it. The script is as below:
if [ $# -ne 2 ]
then
echo "usage: prdel <script file name> <directory in which scripts are present>"
exit 1
fi
file=$1
dir=$2
if [ ! -s ${file} ]
then
echo "script file ${file} either does not exist or is empty (zero bytes)"
echo "Exiting..."
exit 1
fi
if [ ! -d ${dir} ]
then
echo "Invalid directory ${dir} entered"
echo "Exiting..."
exit 1
fi
cordir="./corrected"
prlogdir="./prlog"
if [ -d ${cordir} ]
then
echo "The corrected directory exist in the path, Please remove and run the tool again"
echo "Exiting..."
exit 1
else
mkdir ${cordir}
fi
if [ -d ${prlogdir} ]
then
echo "The prlog directory exist in the path, Please remove and run the tool again"
echo "Exiting..."
exit 1
else
mkdir ${prlogdir}
fi
errFile="$prlogdir/scr_err.rpt"
sucFile="$prlogdir/scr_suc.rpt"
Lines=`wc -l $file`
cntr=1
while [ $cntr -le $Lines ]
do
src=`head -$cntr $file|tail -1`
echo "$cntr. Processing $src...."
srcPath="${dir}/${src}"
if [ ! -s ${srcPath} ]
then
echo "Script file ${src} does not exist in the path given" >> ${errFile}
else
cp $srcPath $cordir/$src.tmp
srctemp="$cordir/$src.tmp"
srccor="$cordir/$src.corrected"
printcnt=`grep -ci "^[ ]*print" $srctemp`
if [ $printcnt -ne 0 ]
then
cat $srctemp|sed 's/^[ ]*[ ]*print[ ]*(/#print(/'|sed 's/^[ ]*[ ]*PRINT[ ]*(/#PRINT(/' > $srccor
mv $srccor $srctemp
fi
prreposcnt=`grep -ci "printrepos" $srctemp`
if [ $prreposcnt -ne 0 ]
then
cat $srctemp|sed 's/^.*urhk_b2k_printRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_B2k_PrintRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_B2k_printRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_b2k_PrintRepos.*/#Printrepos statement removed/' > $srccor
else
cp $srctemp $srccor
fi
echo "Script file $src correction is done" >> ${sucFile}
rm $srctemp
diff $srcPath $srccor >> $prlogdir/$src.diff.rpt
fi
cntr=`expr $cntr + 1`
done
echo "done"
I am completely new to shell scripting. Can anyone help me to modify this script to comment "urhk_b2k_printRepos" lines and also comment "TRACE ON" lines.

Bash script "Syntax Error: Unexpected end of file"

The goal is to create a simple trash utility using a Bourne shell (it's part of an assignment). I am receiving the following error: "line 17: Syntax Error: Unexpected end of file"
I have been staring at the code for a few hours now and I can't see the mistake (probably something simple I am overlooking)
#!/bin/sh
if [$# == 0] ;then
echo "Usage: trash -l | -p | { filename }*"
else
if $1 == '-l'; then
dir $HOME/.trash
else if $1=='-p'; then
rm $HOME/.trash/*
else
for i in ${} ;do
mv i $HOME/.trash
done
fi
fi
Thanks!
This is what I achieved using shellcheck:
#!/bin/sh
if [ $# -eq 0 ] ;then
echo "Usage: trash -l | -p | { filename }*"
else
if [ "$1" = '-l' ]; then
dir "$HOME"/.trash
elif "$1"=='-p'; then
rm "$HOME"/.trash/*
else
for i in ${} ;do
mv "$i" "$HOME"/.trash
done
fi

What is the difference between "else if" and "elif" in bash?

I've got the following shell script that's supposed to simply stage a few Java .ear/.war files to JBoss:
SUCCESS=false
DEPLOY_PATH=/apps/jboss/server/default/deploy
E_NOARGS=75
M_USAGE="usage: $0 {rcm|hcm}"
M_MISSING_RCM="missing: rcm.war file not present"
M_MISSING_HCM="missing: hcm.ear or hcm.war file not present"
if [ -z "$1" ]
then
echo $M_USAGE
exit $E_NOARGS
else
M_START="deploying $1 ..."
M_FINISH="finished deploying $1"
fi
until [ -z "$1" ]
do
echo $M_START
case "$1" in
rcm*)
# do a hot-deploy of the rcm.war file
# TODO: test if rcm.war file is present, error out if not
if [ -e rcm.war ]
then
cp -v rcm.war $DEPLOY_PATH/rcm.war
SUCCESS=true
else
echo $M_MISSING_RCM
fi
;;
hcm*)
# do a shutdown, deploy hcm.war, and restart jboss
ps -ef | awk '/jboss/{print $2}' | xargs kill -s KILL
HCM_DEPLOYED=false
if [ -e hcm.ear ]
then
cp -v hcm.ear $DEPLOY_PATH/hcm.ear
HCM_DEPLOYED=true
else
if [ -e hcm.war ]
then
cp -v hcm.war $DEPLOY_PATH/hcm.war
HCM_DEPLOYED=true
else
echo $M_MISSING_HCM
fi
fi
if $HCM_DEPLOYED ;
then
# TODO: detect the hostname
nohup /apps/jboss/bin/run.sh -b <HOSTNAME> & &> /dev/null
SUCCESS=true
fi
;;
*)
echo $M_USAGE
exit 1
esac
shift
done
if $SUCCESS ;
then
echo $M_FINISH
fi
The section in particular that confuses me is this one:
if [ -e hcm.ear ]
then
cp -v hcm.ear $DEPLOY_PATH/hcm.ear
HCM_DEPLOYED=true
else
if [ -e hcm.war ]
then
cp -v hcm.war $DEPLOY_PATH/hcm.war
HCM_DEPLOYED=true
else
echo $M_MISSING_HCM
fi
fi
I can't seem to get elif [ -e hcm.war ] to work correctly on the remote server. The remote server is running bash 3.2.25 on redhat (if that makes any difference.) I suspect I'm just missing some picky bash shell script detail.
Any suggestions?
Your code as posted seems to work.
There is a difference between elif .. fi AND else ; if ... fi. A true elif ... fi will have one fewer fi at the end than your code.
Your code as posted, asks, "if hcm.ear exists THEN check if there is an hcm.war". Is that what you want? The other logic path to test would be "if hcm.ear doesn't exist THEN check if there an hcm.war."
That alternate logic path looks like
if [ -e hcm.ear ] ; then
cp -v hcm.ear $DEPLOY_PATH/hcm.ear
HCM_DEPLOYED=true
elif [ -e hcm.war ] ; then
cp -v hcm.war $DEPLOY_PATH/hcm.war
HCM_DEPLOYED=true
else
echo $M_MISSING_HCM
fi
I hope this helps.
This isn't a direct answer to the question (elif vs else) but I would refactor like so:
HCM_DEPLOYED=true
cp -v hcm.ear "${DEPLOY_PATH}/" || cp -v hcm.war "${DEPLOY_PATH}/" || HCM_DEPLOYED=false
if [ ! ${HCM_DEPLOYED} ]; then
echo "${M_MISSING_HCM}"
else
# TODO: detect the hostname
...
I.e. always try the copies since you always want to do them, if one fails try the next, etc.
As an aside, you always want to wrap paths and strings in quotes. Otherwise a path containing spaces will cause your app to break.

Check if passed argument is file or directory in Bash

I'm trying to write an extremely simple script in Ubuntu which would allow me to pass it either a filename or a directory, and be able to do something specific when it's a file, and something else when it's a directory. The problem I'm having is when the directory name, or probably files too, has spaces or other escapable characters are in the name.
Here's my basic code down below, and a couple tests.
#!/bin/bash
PASSED=$1
if [ -d "${PASSED}" ] ; then
echo "$PASSED is a directory";
else
if [ -f "${PASSED}" ]; then
echo "${PASSED} is a file";
else
echo "${PASSED} is not valid";
exit 1
fi
fi
And here's the output:
andy#server~ $ ./scripts/testmove.sh /home/andy/
/home/andy/ is a directory
andy#server~ $ ./scripts/testmove.sh /home/andy/blah.txt
/home/andy/blah.txt is a file
andy#server~ $ ./scripts/testmove.sh /home/andy/blah\ with\ a\ space.txt
/home/andy/blah with a space.txt is not valid
andy#server~ $ ./scripts/testmove.sh /home/andy\ with\ a\ space/
/home/andy with a space/ is not valid
All of those paths are valid, and exist.
That should work. I am not sure why it's failing. You're quoting your variables properly. What happens if you use this script with double [[ ]]?
if [[ -d $PASSED ]]; then
echo "$PASSED is a directory"
elif [[ -f $PASSED ]]; then
echo "$PASSED is a file"
else
echo "$PASSED is not valid"
exit 1
fi
Double square brackets is a bash extension to [ ]. It doesn't require variables to be quoted, not even if they contain spaces.
Also worth trying: -e to test if a path exists without testing what type of file it is.
At least write the code without the bushy tree:
#!/bin/bash
PASSED=$1
if [ -d "${PASSED}" ]
then echo "${PASSED} is a directory";
elif [ -f "${PASSED}" ]
then echo "${PASSED} is a file";
else echo "${PASSED} is not valid";
exit 1
fi
When I put that into a file "xx.sh" and create a file "xx sh", and run it, I get:
$ cp /dev/null "xx sh"
$ for file in . xx*; do sh "$file"; done
. is a directory
xx sh is a file
xx.sh is a file
$
Given that you are having problems, you should debug the script by adding:
ls -ld "${PASSED}"
This will show you what ls thinks about the names you pass the script.
Using -f and -d switches on /bin/test:
F_NAME="${1}"
if test -f "${F_NAME}"
then
echo "${F_NAME} is a file"
elif test -d "${F_NAME}"
then
echo "${F_NAME} is a directory"
else
echo "${F_NAME} is not valid"
fi
Using the "file" command may be useful for this:
#!/bin/bash
check_file(){
if [ -z "${1}" ] ;then
echo "Please input something"
return;
fi
f="${1}"
result="$(file $f)"
if [[ $result == *"cannot open"* ]] ;then
echo "NO FILE FOUND ($result) ";
elif [[ $result == *"directory"* ]] ;then
echo "DIRECTORY FOUND ($result) ";
else
echo "FILE FOUND ($result) ";
fi
}
check_file "${1}"
Output examples :
$ ./f.bash login
DIRECTORY FOUND (login: directory)
$ ./f.bash ldasdas
NO FILE FOUND (ldasdas: cannot open `ldasdas' (No such file or directory))
$ ./f.bash evil.php
FILE FOUND (evil.php: PHP script, ASCII text)
FYI: the answers above work but you can use -s to help in weird situations by checking for a valid file first:
#!/bin/bash
check_file(){
local file="${1}"
[[ -s "${file}" ]] || { echo "is not valid"; return; }
[[ -d "${file}" ]] && { echo "is a directory"; return; }
[[ -f "${file}" ]] && { echo "is a file"; return; }
}
check_file ${1}
Using stat
function delete_dir () {
type="$(stat --printf=%F "$1")"
if [ $? -ne 0 ]; then
echo "$1 directory does not exist. Nothing to delete."
elif [ "$type" == "regular file" ]; then
echo "$1 is a file, not a directory."
exit 1
elif [ "$type" == "directory" ]; then
echo "Deleting $1 directory."
rm -r "$1"
fi
}
function delete_file () {
type="$(stat --printf=%F "$1")"
if [ $? -ne 0 ]; then
echo "$1 file does not exist. Nothing to delete."
elif [ "$type" == "directory" ]; then
echo "$1 is a regular file, not a directory."
exit 1
elif [ "$type" == "regular file" ]; then
echo "Deleting $1 regular file."
rm "$1"
fi
}
https://linux.die.net/man/2/stat
https://en.m.wikipedia.org/wiki/Unix_file_types
A more elegant solution
echo "Enter the file name"
read x
if [ -f $x ]
then
echo "This is a regular file"
else
echo "This is a directory"
fi
Answer based on the title:
Check if passed argument is file or directory in Bash
This works also if the provided argument has a trailing slash .e.g. dirname/
die() { echo $* 1>&2; exit 1; }
# This is to remove the the slash at the end: dirName/ -> dirName
fileOrDir=$(basename "$1")
( [ -d "$fileOrDir" ] || [ -f "$fileOrDir" ] ) && die "file or directory $fileOrDir already exists"
Testing:
mkdir mydir
touch myfile
command dirName
# file or directory mydir already exists
command dirName/
# file or directory mydir already exists
command filename
# file or directory myfile already exists
#!/bin/bash
echo "Please Enter a file name :"
read filename
if test -f $filename
then
echo "this is a file"
else
echo "this is not a file"
fi
One liner
touch bob; test -d bob && echo 'dir' || (test -f bob && echo 'file')
result is true (0)(dir) or true (0)(file) or false (1)(neither)
This should work:
#!/bin/bash
echo "Enter your Path:"
read a
if [[ -d $a ]]; then
echo "$a is a Dir"
elif [[ -f $a ]]; then
echo "$a is the File"
else
echo "Invalid path"
fi

Resources