Вы можете использовать функцию pure-ftpd PureDB для создания входа ftp только для службы pure-ftpd.
Вы просто забыли заменить $# на $) element в цикле for:
function nevens {
local sum=0
for element in $@; do
let evencheck=$(( element % 2 ))
if [[ $evencheck -eq 0 ]]; then
let sum=sum+1
fi
done
echo $sum
}
Теперь, чтобы проверить функцию:
$ nevens 42 6 7 9 33
2
$ nevens 42 6 7 9 33 22
3
$ nevens {1..10..2} # 1 to 10 step 2 → odd numbers only
0
$ nevens {2..10..2} # 2 to 10 step 2 → five even numbers
5
Я не уверен, что вы открыты для других решений. Кроме того, я не знаю, можете ли вы использовать внешние утилиты, или если вы ограничены исключительно встроенными bash. Например, если вы можете использовать grep, ваша функция может быть намного проще:
function nevens {
printf "%s\n" "$@" | grep -c '[02468]$'
}
Это помещает каждое целое число ввода в свою собственную строку, а затем использует grep для подсчета строк
Update - @PeterCordes отметил, что мы можем даже сделать это без grep - просто чистый bash, если список ввода содержит только хорошо сформированный целые числа (без десятичных точек):
function nevens{
evens=( ${@/%*[13579]/} )
echo "${#evens[@]}"
}
Это работает, создавая список с именем evens, отфильтровывая все коэффициенты, а затем возвращая длину этого списка.
@dessert нашел основную проблему, я дам некоторый обзор кода:
Shebang: В Ubuntu нет /usr/bin/bash. Это /bin/bash. Хорошо, что вы объявили sum local и избежали загрязнять пространство имен переменных вне функции. Кроме того, вы можете объявить его целочисленной переменной с помощью опции -i:local -i sum=0
Всегда указывайте свои переменные (и параметры)! В этом скрипте нет необходимости, но очень хорошая привычка: for element in "$@"
do
Здесь вы можете опустить in "$@" здесь: for element
do
Когда in <something> не задано, цикл for неявно перебирает аргументы. Это может избежать ошибок, таких как забывание котировок. Нет необходимости вычислять, а затем проверять результат. Вы можете непосредственно выполнить расчет в if: if (( (element % 2) == 0 ))
then
((sum = sum + 1))
fi
(( ... )) - это арифметический контекст. Это более полезно, чем [[ ... ]] для выполнения арифметических проверок, и дополнительно вы можете опустить $ перед переменными (что упрощает чтение, IMHO). Если вы перенесли элемент проверки четности в отдельную функцию, это может улучшить читаемость и повторное использование: function evencheck
{
return $(( $1 % 2 ))
}
function nevens
{
local -i sum=0
for element
do
# `if` implicitly checks that the returned value/exit status is 0
if evencheck "$element"
then
(( sum++ ))
fi
done
echo "$sum"
}
Вы просто забыли заменить $# на $) element в цикле for:
function nevens {
local sum=0
for element in $@; do
let evencheck=$(( element % 2 ))
if [[ $evencheck -eq 0 ]]; then
let sum=sum+1
fi
done
echo $sum
}
Теперь, чтобы проверить функцию:
$ nevens 42 6 7 9 33
2
$ nevens 42 6 7 9 33 22
3
$ nevens {1..10..2} # 1 to 10 step 2 → odd numbers only
0
$ nevens {2..10..2} # 2 to 10 step 2 → five even numbers
5
Я не уверен, что вы открыты для других решений. Кроме того, я не знаю, можете ли вы использовать внешние утилиты, или если вы ограничены исключительно встроенными bash. Например, если вы можете использовать grep, ваша функция может быть намного проще:
function nevens {
printf "%s\n" "$@" | grep -c '[02468]$'
}
Это помещает каждое целое число ввода в свою собственную строку, а затем использует grep для подсчета строк
Update - @PeterCordes отметил, что мы можем даже сделать это без grep - просто чистый bash, если список ввода содержит только хорошо сформированный целые числа (без десятичных точек):
function nevens{
evens=( ${@/%*[13579]/} )
echo "${#evens[@]}"
}
Это работает, создавая список с именем evens, отфильтровывая все коэффициенты, а затем возвращая длину этого списка.
@dessert нашел основную проблему, я дам некоторый обзор кода:
Shebang: В Ubuntu нет /usr/bin/bash. Это /bin/bash. Хорошо, что вы объявили sum local и избежали загрязнять пространство имен переменных вне функции. Кроме того, вы можете объявить его целочисленной переменной с помощью опции -i:local -i sum=0
Всегда указывайте свои переменные (и параметры)! В этом скрипте нет необходимости, но очень хорошая привычка: for element in "$@"
do
Здесь вы можете опустить in "$@" здесь: for element
do
Когда in <something> не задано, цикл for неявно перебирает аргументы. Это может избежать ошибок, таких как забывание котировок. Нет необходимости вычислять, а затем проверять результат. Вы можете непосредственно выполнить расчет в if: if (( (element % 2) == 0 ))
then
((sum = sum + 1))
fi
(( ... )) - это арифметический контекст. Это более полезно, чем [[ ... ]] для выполнения арифметических проверок, и дополнительно вы можете опустить $ перед переменными (что упрощает чтение, IMHO). Если вы перенесли элемент проверки четности в отдельную функцию, это может улучшить читаемость и повторное использование: function evencheck
{
return $(( $1 % 2 ))
}
function nevens
{
local -i sum=0
for element
do
# `if` implicitly checks that the returned value/exit status is 0
if evencheck "$element"
then
(( sum++ ))
fi
done
echo "$sum"
}