Проверьте, является ли переданный аргумент файлом или каталогом в Bash

Вопрос:Я пытаюсь написать чрезвычайно простой script в Ubuntu, который позволил бы мне передать его либо имя файла, либо каталог, и иметь возможность делать что-то конкретное, когда оно является файлом, и что-то еще, когда оно является каталогом, Проблема, с которой я столкнулась, - это когда имя каталога или, возможно, файлы тоже, имеет пробелы или другие эскалатные

Вопрос:

Я пытаюсь написать чрезвычайно простой script в 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

Все эти пути действительны и существуют.

Лучший ответ:

Это должно сработать. Я не знаю, почему это не удается. Вы правильно цитируете свои переменные. Что произойдет, если вы используете этот script с двойным [[ ]]?

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

По крайней мере, напишите код без густого дерева:

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

Использование команды “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

Использование -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

Более элегантное решение

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

Это должно работать:

#!/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 Ответ №6#!/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

Один лайнер

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

результат равен true (0) (dir) или true (0) (файл) или false (1) (ни один)

Оцените статью
Добавить комментарий