전달 된 인수가 Bash의 파일 또는 디렉토리인지 확인하십시오.


156

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

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


5
if- else배쉬의 구조도 지원합니다 elif. 참고로

3
@glenn-흥미롭게도 변수 할당에는 따옴표가 필요하지 않습니다.
John Kugelman

답변:


211

작동합니다. 왜 실패하는지 잘 모르겠습니다. 변수를 올바르게 인용하고 있습니다. 이 스크립트를 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

대괄호는에 대한 bash 확장 [ ]입니다. 공백을 포함하더라도 변수를 인용 할 필요는 없습니다.

시도해 볼만한 가치가 있습니다 : -e경로가 어떤 유형의 파일인지 테스트하지 않고 경로가 존재하는지 테스트하십시오.


9

최소한 덥수룩 한 나무없이 코드를 작성하십시오.

#!/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스크립트에 전달한 이름에 대한 생각 이 표시 됩니다.


4

"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}

빈 파일이 유효하지 않습니다 (빈 파일이 아닌 -s파일, 크기가 0이 아닌 파일을 검사하기 때문에 )? 그리고 블록 스페셜, 캐릭터 스페셜, FIFO 등에 대한 진단을 인쇄하지 않습니까? Symlink는 아마도 링크의 맨 끝에있는 것으로 해석 될 것입니다. 깨진 심볼릭 링크가 더 문제가 있습니다.
Jonathan Leffler 2016 년

편집으로 제안하는 것은, 나는 당신의 논평을 따르지 않습니다
Mike Q

--brief플래그를 사용하십시오 file. directory때만 출력 합니다.
Berkant Ipek

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

일반적으로, 동등한 답변이 이미있는 경우 이전 질문에 새 답변을 추가하지 않아도됩니다. 추가해야 할 놀라운 새 정보가 있지만 꼭 대답해야합니다. 그러나 당신이 말한 것은 이미 언급되었습니다. ( test일반적으로 셸 내장이지만 일반적으로와 같은 실행 파일 /bin/test도 있습니다 /bin/[.)
Jonathan Leffler

1

보다 우아한 솔루션

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

2
명령 행 인수를 사용하는 대신 입력을 요구하는 프롬프트는 일반적으로 "더 우아하지"않습니다. 테스트에서 변수를 인용해야합니다 : if [ -f "$x" ].
Jonathan Leffler 2016 년

1
function check_file_path(){
    [ -f "$1" ] && return
    [ -d "$1" ] && return
    return 1
}
check_file_path $path_or_file

-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

2
질문에 대답 할 때 설명을 추가 할 수 있습니까?
Sébastien Temprado 10

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

질문의 코드와 마찬가지로 출력에 파일 이름을 에코하는 것이 가장 좋습니다. 파일 이름을 묻는 메시지가 개선 된 것은 확실하지 않습니다. 코드는 파일, 디렉토리 및 'other'를 구분하지 않습니다. 답변이 없거나 전할 새로운 정보가있는 경우 이전 질문에 새 답변을 추가해도됩니다. 여기에는 해당되지 않습니다.
Jonathan Leffler 2016 년

-2

짧막 한 농담

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

결과는 true (0) (dir) 또는 true (0) (file) 또는 false (1) (none)입니다


내가 교체하는 경우 touch bobmkdir bob, 나는 출력을 얻을 : dirfile두 줄에.
Jonathan Leffler 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.