Я пытаюсь создать скрипт BASH, который считывает аргументы, проверяет, являются ли они каталогом, обычным файлом, исполняемым файлом или символической ссылкой, и выводит их в терминал.
При выполнении моего скрипта я использую "./myscript.bash *", чтобы увидеть, но я не получаю никаких прогнозируемых результатов. Я получаю имена всех элементов в моем домашнем каталоге, которые являются только "не найдены". Пример:
"Рабочий стол не найден", "Загрузки не найдены" и т. д. ДАЖЕ если они там, в моей домашней папке, и являются каталогами. Кто-нибудь знает, что я делаю не так?
#!/bin/bash
for i in $*; do
if [ -d “{$i}” ]; then
echo “${i} (Directory)”;
elif [ -x “{$i}” ]; then
echo “${i} (Executable)”;
elif [ -h “{$i}” ]; then
echo “${i} (Symbolic)”;
elif [ -f “{$i}” ]; then
echo “${i} (Ordinary)”;
else
echo “${i} not found”
fi
done
решение1
Первое правило отладки простых скриптов:
Если это не сработает, попробуйте повторить.
В этом случае:
for i in $*; do
echo "testing if “{$i}” exists"
if [ -d “{$i}” ]; then
echo “${i} (Directory)”;
<... rest of the script ...>
Вы сразу увидите, что ответ:
testing if “{Downloads}” exists
...
То есть: проверка заключается в том, существует ли ”{Downloads}” (smartquotes-accolade open-Downloads-accolade close smartquotes).
Вероятно, этот каталог не будет существовать.
Умные кавычки могут оказаться упущением для начинающего shell-скриптера. Bash (и большинство других оболочек) очень разборчивы в использовании кавычек. Одинарная кавычка ( '
) имеет другое значение, чем двойная кавычка ( ). Обратные кавычки тоже означают что-то другое. Умные кавычки — это те, что вам дала мама, вообще ничего не делайте (если вы простите мою ссылку на Jefferson Airplane). Вам определенно нужны здесь "
двойные кавычки ( ), потому что они позволяют расширять переменные."
Далее следуют {
и }
. В ваших echo
' вы даете:
echo “${i} not found”
но в if
это {$i}
. Найдите разницу. Если вы использовали
if [ -d "${i}" ]; then
это бы сработало.
Камиль написал в своих комментариях:
Вы почти никогда не хотите
$*
; вы почти всегда хотите"$@"
вместо этого.
и он прав. Существуют целые страницы, посвященные разнице между $*
и "$@"
, но самый простой способ показать разницу — это:
#!/bin/bash
echo ------------------
echo '$*'
for i in $* ; do echo $i ; done
echo ------------------
echo '"$@"'
for i in "$@" ; do echo $i ; done
echo ------------------
(Я назвал этот скрипт a
) и запустите его с помощью:
bash a 'plop 123' plop 123
------------------
$*
plop
123
plop
123
------------------
"$@"
plop 123
plop
123
------------------
решение2
@ljm попал в точку, единственное, что я хотел бы сказать, чтобы развить эту мысль, это всегда возвращаться к желаемому результату и создавать лучшую функциональность вокруг этого.
Короче говоря, сначала убедитесь, что это работает, а затем сделайте так, чтобы это работало лучше.