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