Проблема Bash с аргументами

#!/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, только если оба теста успешно выполнились иначе, это перестанет работать. Но ничто не перестало работать.

Почему?

Заранее спасибо.

2
задан 20 April 2020 в 19:17

2 ответа

Если $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

3
ответ дан 25 April 2020 в 10:44

Позвольте мне также дать этому выстрел. Существующий ответ имеет его право, но так как это - вопрос о 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 или около этого.


Как дальнейшие точки:

  1. если Вы хотите проверить, существует ли пользователь, необходимо использовать id или getent passwd (какой бы ни доступно и более подходит для того, что Вы хотите). Вы могли также использовать eval echo ~$name (если $name содержит имя пользователя). И не, это не ошибка. ~username расширяется до корневого каталога упомянутого пользователя, но только через справку eval (или заполнение клавишей Tab на подсказке).
  2. можно скорее хотеть основывать результаты о данном пользователе (имя) на getent passwd вывод, а не предположения жесткого кодирования такой как, в котором должны быть корневые каталоги /home ...

Но это - просто мои два дополнительных цента... ;)

2
ответ дан 25 April 2020 в 10:44

Другие вопросы по тегам:

Похожие вопросы: