2011-01-12 32 views
73

Tôi đang cố gắng viết một tập lệnh cực kỳ đơn giản trong Ubuntu, cho phép tôi chuyển nó hoặc tên tệp hoặc thư mục và có thể thực hiện điều gì đó cụ thể khi đó là tệp và một thứ khác khi đó là thư mục. Vấn đề tôi gặp phải là khi tên thư mục hoặc các tệp có thể quá, có dấu cách hoặc các ký tự có thể thoát khác có trong tên.Kiểm tra xem đối số đã qua có phải là tệp hoặc thư mục trong BASH

Đây là mã cơ bản của tôi ở dưới đây và một vài bài kiểm tra.

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

Và đây là kết quả:

[email protected]~ $ ./scripts/testmove.sh /home/andy/ 
/home/andy/ is a directory 

[email protected]~ $ ./scripts/testmove.sh /home/andy/blah.txt 
/home/andy/blah.txt is a file 

[email protected]~ $ ./scripts/testmove.sh /home/andy/blah\ with\ a\ space.txt 
/home/andy/blah with a space.txt is not valid 

[email protected]~ $ ./scripts/testmove.sh /home/andy\ with\ a\ space/ 
/home/andy with a space/ is not valid 

Tất cả những đường dẫn có giá trị, và tồn tại.

+4

'cấu trúc if'-'else' trong Bash cũng hỗ trợ' elif'. Chỉ là FYI. –

+0

nên có dấu ngoặc kép ở đây: 'PASSED =" $ 1 "' –

+3

@glenn - Thật kỳ lạ, dấu ngoặc kép không bắt buộc trong các bài tập biến. –

Trả lời

102

Điều đó sẽ hiệu quả. Tôi không chắc tại sao nó không thành công. Bạn đang trích dẫn các biến của mình đúng cách. Điều gì xảy ra nếu bạn sử dụng tập lệnh này với một đôi [[]]?

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 

Dấu ngoặc vuông kép là phần mở rộng bash là [ ]. Nó không yêu cầu các biến được trích dẫn, ngay cả khi chúng chứa dấu cách.

Cũng đáng thử: -e để kiểm tra xem đường dẫn có tồn tại mà không kiểm tra loại tệp đó không.

7

Ít nhất viết mã mà không có cây rậm:

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

Khi tôi đặt đó vào một tập tin "xx.sh" và tạo ra một tập tin "xx sh", và chạy nó, tôi nhận được:

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

cho rằng bạn đang gặp vấn đề, có lẽ bạn nên gỡ lỗi kịch bản bằng cách thêm một dòng:

ls -l "${PASSED}" 

này sẽ hiển thị bạn những gì ls suy nghĩ về tên bạn vượt qua kịch bản.

-1

CẬP NHẬT: Tôi đã bị bỏ phiếu vì vậy tôi đã quyết định viết lại câu trả lời của mình, cảm ơn phản hồi.

Sử dụng "file" lệnh có thể hữu ích cho việc này:

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

Output ví dụ:

$ ./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) 

FYI: câu trả lời ở trên công việc nhưng bạn có thể sử dụng -s để giúp đỡ trong những tình huống kỳ lạ bằng cách kiểm tra tệp hợp lệ trước tiên:

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

Sử dụng -f-d công tắc trên /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 
Các vấn đề liên quan