Оболочка рыбы: проверьте, предоставлен ли аргумент для функции
Я создаю функцию (ниже), с помощью которой вы можете предоставить аргумент, каталог. Я тестирую, если $argv
- это каталог с параметром -d
, но он, похоже, не работает, он всегда возвращает true, даже если аргументы не указаны. Я также опробовал test -n $argv -a -d $argv
, чтобы проверить, что $argv
- пустое sting, но возвращает ошибку test: Missing argument at index 1
. Как проверить, предоставлен ли какой-либо аргумент функции или нет? Почему test -d $argv
не работает, из моего понимания это должно быть ложным, если аргумент не указан, потому что пустая строка не является каталогом.
function fcd
if test -d $argv
open $argv
else
open $PWD
end
end
Спасибо за помощь.
Ответы
Ответ 1
count
- правильный способ сделать это. Для общего случая проверки наличия аргументов вы можете использовать его статус выхода:
function fcd
if count $argv > /dev/null
open $argv
else
open $PWD
end
end
Чтобы ответить на ваш второй вопрос, test -d $argv
возвращает true, если $argv
пуст, потому что POSIX требует, чтобы, когда test
передается один аргумент, он должен "Exit true (0), если $1 не является нулевым, exit false". Поэтому, когда $argv пуст, test -d $argv
означает test -d
, который должен выйти из true, потому что -d
не пуст! Argh!
edit Добавлен недостающий end
, благодаря Ismail для заметок
Ответ 2
В рыбе 2.1+, по крайней мере, вы можете назвать свои аргументы, что затем позволяет использовать более семантический код:
function fcd --argument-names 'filename'
if test -n "$filename"
open $filename
else
open $PWD
end
end
Ответ 3
$argv
- это список, поэтому вы хотите посмотреть на первый элемент, если в нем есть элементы:
if begin; test (count $argv) -gt 0; and test -d $argv[1]; end
open $argv[1]
else
open $PWD
end
Ответ 4
Возможно, это не связано, но я хотел бы добавить еще одну перспективу для вопроса.
Я хочу расширить понимание в более широком круге сферы тестирования кода оболочки с библиотеками, разработанными в группе рыбаков.
С mock вы можете проверить, называется ли команда open безопасно без побочных эффектов.
Пример:
function fcd
if count $argv > /dev/null
open $argv
else
open $PWD
end
end
mock open 0 "echo \$args"
fcd "cool" # echoes cool
mock open 0 "echo \$args"
fcd # echoes $PWD
Является недавней библиотекой, но это может помочь проверить вещи, которые могут быть опасны, например, например, rm
mock rm 0 "echo nothing would happen on \$args"
rm "some file" # simply echoes the message with a list of the files that would been affected
Надеюсь, что это даст более точную точку зрения
P.S.: Извините за откровенную рекламу, но я думаю, что это классная идея, которая была бы неплохо принята сценаристами оболочки, чтобы проверить и добавить устойчивость к сценариям оболочки, это орехи.: P
EDIT: Недавно я заметил ошибку, которую я опубликовал. Пожалуйста, не используйте rm *, потому что звездочка не рассматривается как параметр, вместо этого shell shell расширяет звездочку до списка найденных файлов, и команда только извиняет первый вызов, это означает, что первый файл будет игнорироваться макетом, но все последующие файлы будут удалены, поэтому будьте осторожны, если попробуйте образец и используйте один файл для примера, а не подстановочный знак.