#!/bin/bash
dir=/home/john
name="kate"
if [ -d $dir ] && [ -n $name ]; then
echo "The name exists and the folder $dir exists."
else
echo "Fail"
fi
Я просто выполняю эту команду, и она не работала вообще. Эта команда должна возвратить true, только если оба теста успешно выполнились иначе, это перестанет работать. Но ничто не перестало работать.
Почему?
Заранее спасибо.
Если $dir
или $name
пусты, затем [ -d $dir ]
или [ -n $name ]
оценит ПРАВДА, потому что они становятся [ -d ]
и [ -n ]
которые тестируют на ненулевую длину литеральных строк -d
и -n
, как обсуждено более подробно в ответах на этот связанный вопрос:
Напр.
$ name=
$ [ -n $name ] && echo true || echo false
true
$ [ -n "$name" ] && echo true || echo false
false
Таким образом, необходимо использовать
if [ -d "$dir" ] && [ -n "$name" ]; then
Однако, если Вы хотите знать ли файл $dir/$name
существует, необходимо сделать это с единственным тестом
if [ -f "$dir/$name" ]
как отмечено в комментарии @bac0n
Позвольте мне также дать этому выстрел. Существующий ответ имеет его право, но так как это - вопрос о Bash, я могу предложить использовать Bashism?
#!/usr/bin/env bash
# Using $HOME so it should exist whenever someone tests this code
# btw: dir is not the best name here ... (shadows /bin/dir from coreutils)
dir=$HOME
name="kate"
if [[ -d $dir ]] && [[ -n $name ]]; then
echo "The name exists and the folder $dir exists."
else
echo "Fail"
fi
Вы видите встроенный комментарий. Я также удалил дополнительные пустые строки.
Основной момент - то, что я использую [[
вместо [
(и соответствующий дубликат ]]
вместо ]
).
Для ссылки можно хотеть считать вывод help [
и help [[
. Короче говоря [[
расширенная версия, которая также оказывает поддержку регулярного выражения и более умна во многих других случаях. Я сделал привычкой использовать это вместо [ expression ]
каждый раз, когда мне разрешают предшествовать совместимости с плоскостью оболочка POSIX.
Я не уверен, что это может правильно упоминаться как "ошибка" (дефект). Я держал бы это, это, вероятно, должно обратной совместимости. Но я не на 100% уверен, шифровалось ли воображаемое "ошибочное" поведение на самом деле в стандарте POSIX или около этого.
Как дальнейшие точки:
id
или getent passwd
(какой бы ни доступно и более подходит для того, что Вы хотите). Вы могли также использовать eval echo ~$name
(если $name
содержит имя пользователя). И не, это не ошибка. ~username
расширяется до корневого каталога упомянутого пользователя, но только через справку eval
(или заполнение клавишей Tab на подсказке).getent passwd
вывод, а не предположения жесткого кодирования такой как, в котором должны быть корневые каталоги /home
...Но это - просто мои два дополнительных цента... ;)