Перевірте, чи існує каталог з використанням домашнього символу (~) в 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(або якимись іншими динамічними засобами) і хоче розгорнути тильду.

Питання стає "Як виконати розширення tilde на вмісті змінної?"

Загальний підхід полягає у використанні 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

Тепер, коли користувач набере вкладку "tilde" та "hits", вона розшириться. Цей підхід не замінює підхід eval вище, однак, оскільки розширення відбувається лише в тому випадку, якщо користувач натискає вкладку. Якщо він просто набере ~ / foo і натисне вхід, він залишиться як тильда.

Дивись також:


23

Видаліть подвійні лапки навколо каталогу, щоб побачити, чи працює він:

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

Причиною цього є те, що розширення tilde працює лише тоді, коли воно не цитується.

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
Розширення Tilde робиться, коли змінна встановлюється, а не коли її оцінюють, тому це не є справедливим прикладом.
MadHatter

+1, цього достатньо, щоб вирішити мою проблему.
Літаючий Фішер

4

Він працює не тільки на Mac, але і на будь-якій платформі, на якій працює bash.

Коли ви цитуєте "~ / Desktop", ви говорите bash шукати Desktop у папці ~. Цитата знімає спеціальне призначення ~

Дивіться - http://www.gnu.org/software/bash/manual/bashref.html#Tilde-Expansion

Видаліть подвійні лапки, і це повинно працювати.


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 замість ~

~ - КЛЮЧОВА річ


Якщо ви прочитаєте іншу відповідь тут, то зрозумієте, що це неправильно.
пташенята
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.