Проверить, существует ли каталог, используя домашний символ (~) в bash.

16

Почему следующая bashпроверка, если каталог не удается?

if [ ! -d "~/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

~/Desktopдействительно существует. Это на Mac, кстати.


Проблема с этим типом скрипта

read -p "Provide the destination directory: " DESTINATION

if [ ! -d $DESTINATION ]; then
    echo "\t'$DESTINATION' does not exist." >&2;
    exit 1;
fi
Джастин
источник
1
Также как когда вы делаете, cd "~/Desktop"вы также получаете ошибку. Он должен быть заключен в кавычки или сохранен как переменная (без кавычек). Например, a=~/Desktop; cd $a;работает, но не a="~/Desktop"; cd Desktop;смотри. Serverfault.com/questions/417252/…
dylnmc

Ответы:

7

Джастин разъяснил свой вопрос в своем первом комментарии к ответу Кванты. Он читает строку текста, используя read(или каким-либо другим динамическим способом) и хочет расширить тильду.

Возникает вопрос: «Как выполнить расширение тильды для содержимого переменной?»

Общий подход заключается в использовании eval, но он сопровождается некоторыми важными оговорками, а именно пробелами и выходным перенаправлением ( >) в переменной. Кажется, мне подходит следующее:

read -p "Provide the destination directory: " DESTINATION

if [ ! -d "`eval echo ${DESTINATION//>}`" ]; then
    echo "'$DESTINATION' does not exist." >&2;
    exit 1;
fi

Попробуйте это с каждым из следующих входов:

~
~/existing_dir
~/existing dir with spaces
~/nonexistant_dir
~/nonexistant dir with spaces
~/string containing > redirection
~/string containing > redirection > again and >> again

объяснение

  • ${mypath//>}Полоски из >символов , которые могут затирать файл во время eval.
  • Это eval echo ...то, что фактическое расширение тильды
  • Двойные кавычки вокруг evalдля поддержки имен файлов с пробелами.

В дополнение к этому вы можете улучшить UX, добавив -eопцию:

read -p "Provide the destination directory: " -e DESTINATION

Теперь, когда пользователь вводит тильду и нажимает на вкладку, она будет расширяться. Однако этот подход не заменяет вышеприведенный подход, поскольку расширение происходит только в том случае, если пользователь нажимает вкладку. Если он просто наберет ~ / foo и нажмет enter, он останется тильдой.

Смотрите также:

Ноах Магедман
источник
23

Удалите двойные кавычки вокруг каталога, чтобы увидеть, работает ли он:

if [ ! -d ~/Desktop ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

Причина в том, что расширение тильды работает только тогда, когда оно не заключено в кавычки.

info "(bash) Tilde Expansion"

3.5.2 Tilde Expansion
---------------------

If a word begins with an unquoted tilde character (`~'), all of the
characters up to the first unquoted slash (or all characters, if there
is no unquoted slash) are considered a TILDE-PREFIX.  If none of the
characters in the tilde-prefix are quoted, the characters in the
tilde-prefix following the tilde are treated as a possible LOGIN NAME.
If this login name is the null string, the tilde is replaced with the
value of the `HOME' shell variable.  If `HOME' is unset, the home
directory of the user executing the shell is substituted instead.
Otherwise, the tilde-prefix is replaced with the home directory
associated with the specified login name.
кванты
источник
Как насчет, если значение приходит динамически. Т.е. ( pastie.org/4471350 ) и DESTINATIONесть ~/Desktop.
Джастин
3
Расширение тильды выполняется, когда переменная установлена, а не когда она оценивается, так что это не лучший пример.
MadHatter
+1, этого достаточно, чтобы решить мою проблему.
Flying Fisher
4

Он не работает не только на Mac, но и на любой платформе, на которой работает bash.

Когда вы цитируете «~ / Desktop», вы говорите bash искать Desktop внутри папки ~. Цитата удаляет специальную цель ~

Смотрите - http://www.gnu.org/software/bash/manual/bashref.html#Tilde-Expansion

Удалите двойные кавычки, и это должно работать.

Chida
источник
1

бегать

echo $HOME

используйте $HOMEи убедитесь, что пользователь действительно использует скрипт. если root использует ~его /root, то нет /home/$USER.

if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi
три шестерки
источник
-1
if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

должен быть $ HOME вместо ~

~ вещь КЛАВИАТУРЫ

LeoChu
источник
Если вы прочитаете другой ответ здесь, вы поймете, что это неправильно.
птенцы