Я все еще новичок в unix и сценариях, и я пытаюсь написать сценарий, который может принимать входной каталог от пользователя, проверять, существует ли он, затем сравните количество файлов в данном каталоге с текущим каталогом и сообщите, в котором больше файлов. Мой код в основном работает, пока я ввожу дочерний каталог. Если я попытаюсь использовать сценарий и ввести родительский или другой дочерний элемент в другую ветку, он не сможет найти каталог, даже если указан полный путь. Я знаю, что аналогичные вопросы были заданы относительно команды test, но ни один из них (который я смог найти) не касался того, что делать, когда test не может распознать каталог, который действительно существует.
dir1=$(pwd)
read -rp "Input the path..." dir2
if [ ! -d "$dir2" ]; then
echo "...does not exist"
else
...
... остальная часть кода работает нормально. В этом и кроются проблемы.
РЕДАКТИРОВАТЬ: Общая идея состоит в том, чтобы найти любой каталог из любого другого каталога, но этого не происходит. Например, из моего ~ / public_html как pwd, если я запускаю скрипт и ввожу ~ / schoolwork или даже полный путь, он не может распознать каталог.
Я также изменил логику (так что моя функция проверяет, существует ли она, затем выполняет операции, иначе возвращает ошибку), а также метод, размещенный здесь. результаты такие же.
Вы можете сделать свой сценарий оболочки следующим образом:---
#!/bin/bash
read -rp "Input the path..." dir2
dir1=$pwd
#First Check the existence of directory
if [[ -d "$dir2" ]]
then
#If it is a valid directory then count the number of files in each directory
count1=$(find $dir1 -type f | wc -l)
count2=$(find $dir2 -type f | wc -l)
#Compare the number of files in the two directories
if [ $count1 -gt $count2 ]
then
echo "Current Directory has more files"
else if [ $count1 -eq $count2 ]
then
echo "Both Directories have same number of files"
else
echo "Input Directory has greater number of files"
fi
fi
else
#If not a valid directory
echo "Invalid Directory"
fi
Проблема, с которой вы столкнулись, связана с расширением тильды. Если вы введете ~/schoolwork
в приглашении вашего сценария, тильда в начале будет просто еще одним символом и не будет расширена до пути к вашему домашнему каталогу, когда вы проверите его с помощью [ ! -d "$dir2" ]
. Точно так же вы не сможете ввести $HOME/schoolwork
, так как переменная $HOME
никогда не будет расширена.
Как правило, предлагать пользователю вводить пути — плохая идея. Пути намного проще вводить в командной строке, где и тильды, и переменные раскрываются перед выполнением скрипта или программы. Кроме того, указание имени пути в командной строке позволит пользователю использовать завершение с помощью табуляции -, что, в свою очередь, снизит риск опечаток.
Итак, вы хотите, чтобы ваш пользователь использовал ваш скрипт как
./script.sh path/to/some/directory
Например,
./script.sh ~/schoolwork
Здесь оболочка расширила бы путь перед вызовом вашего скрипта, и скрипт получил бы путь вроде /home/turfer/schoolwork
в качестве своего первого и единственного аргумента.
Итак, как написать этот скрипт?
Вот предложение для начала:
#!/bin/bash
userdir=$1 # the directory pathname passed on the command line
if [ ! -d "$userdir" ]; then
printf 'Your directory, %s, does not exist\n' "$userdir" >&2
exit 1
fi
Теперь нам нужно подсчитать количество файлов как в текущем каталоге, так и в $userdir
. Предположим, что мы действительно имеем в виду файлы любого типа (, включая сокеты, символические ссылки, каталоги и т. д. ).
shopt -s dotglob # also match hidden names
herefiles=(./* )
therefiles=( "$userdir"/* )
Если вы хотите подсчитывать только обычные файлы , вы должны циклически перебирать вещи, соответствующие этим двум шаблонам, и рассматривать только те вещи, которые проходят [ -f... ]
тест (, хотя это все равно будет учитываться. символические ссылки на обычные файлы ).
Теперь у нас есть все имена всего в текущем каталоге и в указанном пользователем -каталоге в двух массивах. Теперь нам просто нужно сравнить длины этих массивов и сказать, какой из них самый длинный.
if [ "${#herefiles[@]}" -gt "${#therefiles[@]}" ]; then
printf 'There are more files here than in %s\n' "$userdir"
elif [ "${#herefiles[@]}" -lt "${#therefiles[@]}" ]; then
printf 'There are more files in %s than in here\n' "$userdir"
else
printf 'There are an equal number of files here as in %s\n' "$userdir"
fi
Вместо того, чтобы хранить имена файлов в двух отдельных массивах, вы могли бы также вручную подсчитать имена в двух циклах.