我正在尝试在Ubuntu中编写一个极其简单的脚本,它将允许我传递它一个文件名或目录,并且能够在它是一个文件时做一些特定的事情,当它是一个目录时做一些其他的事情。我遇到的问题是,当目录名,或可能文件,有空格或其他可转义字符在名称中。

下面是我的基本代码,还有几个测试。

#!/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

这是输出:

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

所有这些路径都是有效的,并且存在。


当前回答

#!/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 

其他回答

#!/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 

使用统计

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

根据题目回答:

在Bash中检查传递的参数是否为文件或目录

如果提供的参数后面有斜杠,也可以这样做。目录名/

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"

测试:

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

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

当我把它放入一个文件“xx.sh”,并创建一个文件“xx sh”,并运行它,我得到:

$ 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
$

如果您遇到了问题,您应该通过添加以下内容来调试脚本:

ls -ld "${PASSED}"

这将显示ls对传递脚本的名称的想法。

这应该有用。我不知道为什么会失败。你正确地引用了变量。如果使用双[[]],会发生什么?

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

双方括号是对[]的bash扩展。它不要求变量被引用,即使它们包含空格。

同样值得尝试:-e测试路径是否存在,而不测试它是什么类型的文件。