我正在尝试在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
所有这些路径都有效且存在。
答案 0 :(得分:154)
那应该有用。我不知道为什么会失败。你正确地引用你的变量。如果您将此脚本与双[[
]]
一起使用会发生什么?
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
测试路径是否存在而不测试它是什么类型的文件。
答案 1 :(得分:8)
至少在没有浓密树的情况下编写代码:
#!/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 -l "${PASSED}"
这将显示ls
对您传递脚本的名称的看法。
答案 2 :(得分:2)
更新: 我被downvoted所以我决定重新写我的答案,谢谢你的反馈。
使用“file”命令可能对此有用:
#!/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}
输出示例:
$ ./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)
仅供参考:上述答案可以通过先检查有效文件来使用-s来帮助处理奇怪的情况:
#!/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}
答案 3 :(得分:2)
在-f
上使用-d
和/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
答案 4 :(得分:2)
更优雅的解决方案
echo "Enter the file name"
read x
if [ -f $x ]
then
echo "This is a regular file"
else
echo "This is a directory"
fi
答案 5 :(得分:0)
function check_file_path(){
[ -f "$1" ] && return
[ -d "$1" ] && return
return 1
}
check_file_path $path_or_file
答案 6 :(得分:-1)
#!/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
答案 7 :(得分:-1)
一支班轮
touch bob; test -d bob && echo 'dir' || (test -f bob && echo 'file')
结果为true(0)(dir)或true(0)(file)或false(1)(都不是)
答案 8 :(得分:-1)
这应该起作用:
#!/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