Назад | Перейти на главную страницу

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

Почему следующее 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

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

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.

Джастин пояснил свой вопрос в своем первом комментарии к ответу квантов. Он читает строку текста, используя 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

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

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

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

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

Видеть -- http://www.gnu.org/software/bash/manual/bashref.html#Tilde-Expansion

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

бегать

echo $HOME

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

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

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

~ это КЛАВИАТУРА