Я пытаюсь выполнить код ниже, но когда я пытаюсь использовать свою функцию в операторе if, я получаю -bash: [: too many arguments
ошибку. Почему это происходит?
Заранее спасибо!
notContainsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 1; done
return 0
}
list=( "pears" "apples" "bananas" "oranges" )
blacklist=( "oranges" "apples" )
docheck=1
for fruit in "${list[@]}"
do
if [ notContainsElement "$fruit" "${blacklist[@]}" -a $docheck = 1 ]
then
echo $fruit
fi
done
Ответы:
При использовании
if [ ... ]
вы фактически используете[
утилиту (которая аналогична,test
но требует, чтобы последний аргумент был]
).[
не понимает, чтобы запустить вашу функцию, он ожидает строки. К счастью, здесь вам вообще не нужно использовать[
(по крайней мере, для этой функции):Обратите внимание, что я также сначала проверяю целое число, чтобы мы могли вообще не вызывать функцию, если
$docheck
не равен 1.Это работает, потому что
if
принимает произвольную команду и решает, что делать из состояния выхода этой команды. Здесь мы используем[ ... ]
тест вместе с вызовом вашей функции с&&
промежуточным созданием составной команды. Состояние выхода составной команды будет истинным, если и[ ... ]
тест, и функция вернули ноль в качестве своих состояний выхода, сигнализируя об успехе.Как примечание стиля, у меня не было бы функционального теста, если массив не содержит элемент, но если ли содержит элемент, и затем
Имея тестовую функцию отрицательный испортит логику в тех случаях , когда вы делаете хотите проверить , содержит ли массив элемента (
if ! notContainsElement ...
).источник
пытаться
-a
опция не является ни оболочкой, ниtest
опциейздесь у вас есть две части теста
Вы связываете тогда,
if
используякак указано выше,
-a
это тестовый вариант, но он может использоваться только с другим тестовым вариантом, поэтому вы можете использоватьчтобы проверить, что
$a
ниже, чем оба$b
и$c
, но вы не можете использовать другие команды в рамках теста.источник
-a
Это тестовый вариант, это означает, что И.$docheck
, без кавычек$a
/$b
/ etc в последнем примере).Вот альтернатива, которая может не понравиться некоторым людям. Преобразуйте массив из черного списка в строку и посмотрите, совпадает ли строка с удаленным фруктом. Отредактировано, чтобы дополнить строки пробелами. Спасибо Скотту за указание на проблему с яблоками и ананасами.
Я думаю, что это проще, но не хватает логики &&, которую многие предпочитают.
источник
list
плодов содержится в одном изblacklist
плодов. Например, если мы изменимblacklist
на( "oranges" "pineapples" )
, вывод вашего скрипта не изменится. … (Продолжение)&&
? (3) Когда вы публикуете код, сделайте соответствующий отступ.two words
и два последующих элементаtwo
иwords
. И если бы ваш список содержался*
как запись, он бы соответствовал всему. (И потому , что вы не цитируя$f
в том, что должно бытьecho "$f"
, если вы даже пытаться повторить такой элемент, он будет заменен списком имен файлов в текущем каталоге).