Передача блока кода как скоро. функция

Не ясно, нужно ли Вам использование на целевой IP, но vnstat является полезным инструментом для записи транспортного использования на интерфейс. Установите его и затем работайте vnstat -u -i eth0 для каждого интерфейса Вы хотите контролировать. Затем получить использование на дневное использование vnstat -i eth0 -d.

9
01.07.2013, 01:17
3 ответа

Это самое короткое решение, которое я смог придумать:

Учитывая эти функции:

# List processing
map() { while IFS='' read -r x; do "$@" "$x"; done; }
filter() { while IFS='' read -r x; do "$@" "$x" >&2 && echo "$x"; done; }
foldr() { local f="$1"; local result="$2"; shift 2;  while IFS='' read -r x; do result="$( "$f" "$@" "$x" "$result" )"; done; echo "$result"; }
foldl() { local f="$1"; local result="$2"; shift 2;  while IFS='' read -r x; do result="$( "$f" "$@" "$result" "$x" )"; done; echo "$result"; }

# Helpers
re() { [[ "$2" =~ $1 ]]; }

Примеры:

# Example helpers
toLower() { tr '[:upper:]' '[:lower:]'; }
showStructure() { [[ "$1" == "--curly" ]] && echo "{$2; $3}" || echo "($1, $2)"; }

# All lib* directories, ignoring case, using regex
ls /usr | map toLower | filter re 'lib.*'

# All block devices. (Using test, for lack of a full bash [[ … ]].)
cd /dev; ls | filter test -b

# Show difference between foldr and foldl
$ ls / | foldr showStructure '()'
(var/, (usr/, (tmp/, (sys/, (sbin/, (run/, (root/, (proc/, (opt/, (mnt/, (media/, (lost+found/, (lib64/, (lib32/, (lib@, (home/, (etc/, (dev/, (daten/, (boot/, (bin/, ())))))))))))))))))))))
$ ls / | foldr showStructure '{}' --curly
{var/; {usr/; {tmp/; {sys/; {sbin/; {run/; {root/; {proc/; {opt/; {mnt/; {media/; {lost+found/; {lib64/; {lib32/; {lib@; {home/; {etc/; {dev/; {daten/; {boot/; {bin/; {}}}}}}}}}}}}}}}}}}}}}}

(Эти примеры, конечно, просто примеры использования, и в реальности этот стиль имеет смысл только для более сложных случаев использования)

Вообще, всегда можно использовать следующий стиль:

f() { something "$@"       ; }; someList    | map    f
g() { something "$1" "$2" …; }; someCommand | filter g
⋮                              ⋮            ⋮     ⋮

Это не совсем лямбда, но очень очень близко. Только несколько лишних символов.

Но любое из следующих удобных сокращений не работает, насколько я могу судить:

λ() { [[ $@ ]]; } # fails on spaces
λ() { [[ "${@:-1}" ${@:1:-1} ]]; } # syntax error
alias λ=test # somehow ignored

К сожалению, bash не очень хорошо подходит для этого стиля, хотя некоторые его функции имеют очень функциональный стиль.

2
27.01.2020, 20:06

Нет, удар не имеет анонимных функций. Однако возможно передать имя функции и аргументы, как строки и иметь удар называют его.

function wrap() {
    do_before
    "$@"
    do_after
}

wrap do_something with_arguments

Это однако, несколько ограничено. Контакт с заключением в кавычки может стать проблемой. Передача больше чем одной команды является также сложностью.

3
27.01.2020, 20:06
  • 1
    Не nightname, все, что необходимо сделать, измениться $* кому: "$@" –  glenn jackman 30.06.2013, 14:39
  • 2
    Многострочные тела функции должны хорошо работать с этим методом. –   30.06.2013, 15:24
  • 3
    Glenn, я забыл о той форме, спасибо. Это не полностью решает проблему заключения в кавычки все же. Evan, единственная команда, перенесенная по нескольким строкам, хорошо работал бы, я означал иметь больше чем одну команду в теле согласно примерам в вопросе. Я обновлю свой ответ для обращения к обоим комментариям. –  David Baggerman 01.07.2013, 00:58

Можно поместить код в строку и передать его eval или sh или просто интерполируйте его.

perform () {
  "$@"
}

perform echo "moo"

Можно быстро закончить в глубокой проблеме заключения в кавычки, все же.

3
27.01.2020, 20:06
  • 1
    На самом деле, я искал perform { echo "moo" \n echo "moo moo" \n echo "moo moo moo" }. Я уже знал, что можно передать одну команду. Но, я ищу несколько строк, не всего одну команду или одну строку. Спасибо, хотя для попытки. –  dgo.a 02.07.2013, 13:41

Теги

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