Check if passed argument is file or directory in Bash
我正在尝试在Ubuntu中编写一个非常简单的脚本,它允许我将文件名或目录传递给它,当它是一个文件时,我可以做一些特定的事情,当它是一个目录时,我可以做一些其他的事情。我遇到的问题是,当目录名,或者可能是文件名中包含空格或者其他可脱离字符时。
下面是我的基本代码和一些测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/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 |
输出结果如下:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
所有这些路径都是有效的,并且存在。
那应该管用。我不知道为什么会失败。你正确地引用了你的变量。如果将此脚本与double
1 2 3 4 5 6 7 8 | 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 |
双方括号是对
同样值得尝试的是:
至少在没有茂密树的情况下编写代码:
1 2 3 4 5 6 7 8 9 10 11 | #!/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"并运行它时,我得到:
1 2 3 4 5 6 | $ 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 $ |
考虑到您有问题,应该通过添加以下内容来调试脚本:
1 | ls -l"${PASSED}" |
这将向您展示
更优雅的解决方案
1 2 3 4 5 6 7 8 | echo"Enter the file name" read x if [ -f $x ] then echo"This is a regular file" else echo"This is a directory" fi |
使用
1 2 3 4 5 6 7 8 9 10 11 | 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 |
更新:我被否决了,所以我决定重新写我的答案,谢谢你的反馈。
使用"file"命令可能有助于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/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} |
输出示例:
1 2 3 4 5 6 | $ ./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来帮助在奇怪的情况下,首先检查有效的文件:
1 2 3 4 5 6 7 8 9 10 | #!/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} |
一班轮
1 | touch bob; test -d bob && echo 'dir' || (test -f bob && echo 'file') |
结果为真(0)(dir)或真(0)(file)或假(1)(两者都不是)
1 2 3 4 5 6 7 8 9 | #!/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 |