programing

전달된 인수가 Bash의 파일 또는 디렉토리인지 확인합니다.

instargram 2023. 5. 2. 22:16
반응형

전달된 인수가 Bash의 파일 또는 디렉토리인지 확인합니다.

저는 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

이러한 모든 경로는 유효하며 존재합니다.

그러면 되겠군요.나는 그것이 왜 실패하는지 확신할 수 없습니다.변수를 적절하게 인용하고 있습니다.이 스크립트를 이중으로 사용하면 어떻게 됩니까?[[ ]]?

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파일 형식을 테스트하지 않고 경로가 존재하는지 테스트합니다.

적어도 부쉬 트리 없이 코드를 작성합니다.

#!/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 " 파일에 넣고 "xxsh" 파일을 만들고 실행하면 다음과 같은 결과를 얻을 수 있습니다.

$ 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당신이 대본을 전달한 이름에 대해 생각합니다.

사용.-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

다음과 같은 경우 "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}

사용.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
}

보다 우아한 솔루션

echo "Enter the file name"
read x
if [ -f $x ]
then
    echo "This is a regular file"
else
    echo "This is a directory"
fi

제목에 따른 답변:

전달된 인수가 Bash의 파일 또는 디렉토리인지 확인합니다.

이것은 제공된 인수에 후행 슬래시가 있는 경우에도 작동합니다.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"

테스트:

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 

원 라이너

touch bob; test -d bob && echo 'dir' || (test -f bob && echo 'file')

결과가 참(0)(수정)이거나 참(0)(파일)이거나 거짓(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

언급URL : https://stackoverflow.com/questions/4665051/check-if-passed-argument-is-file-or-directory-in-bash

반응형