Как я могу создать локальную функцию в моем bashrc?

40

Мой .bashrc имел некоторый повторяющийся код, поэтому я использовал функцию, чтобы упростить его

do_stuff() {
  local version=$1
  export FOO_${version}_X="17"
  export FOO_${version}_Y="42"
}

do_stuff '5.1'
do_stuff '5.2'

Однако теперь, когда я использую свою оболочку, имя «do_stuff» находится в области видимости, поэтому я могу завершить табуляцию и запустить эту функцию (что может привести к путанице в переменных среды). Есть ли способ сделать "do_stuff" видимым только внутри .bashrc?

hugomg
источник
2
Если вы не нуждались в экспорте, вы также можете использовать ()для создания подоболочки. Другой возможностью для простых случаев является использование for version in 5.1 5.2цикла, хотя это позволяет versionизбежать.
Сиро Сантилли 事件 改造 中心 法轮功 六四 事件

Ответы:

40

Используйте в unsetкачестве последней строки в вашем .bashrc:

unset -f do_stuff

удалит / отменит функцию do_stuff.

Для удаления / сброса переменных вызовите его следующим образом:

unset variablename
хаос
источник
Unset действительно единственный путь здесь? Ну, я думаю, что если я буду использовать действительно длинное и уродливое имя для своей функции, вероятность того, что оно столкнется с чем-то другим, не будет такой большой ...
hugomg
Если это проблема проверки Фрист , если функция существует: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
хаос
8
Это не будет работать, если do_stuffиспользуется внутри другой функции. Когда вы вызовете эту функцию, вы получите bash: do_stuff: command not found. Я знаю, что это не тот случай, о котором говорил опер, но на это стоит обратить внимание.
Бурхан Али
Ницца и POSIX .
Сиро Сантилли 新疆 新疆 中改造 心 六四 事件
15

Другой вариант - использовать подчеркивания, как в других скриптовых языках, чтобы указать, что вы не намерены делать эту функцию общедоступной. Вероятность того, что вы введете _do_foo, довольно мала и также вряд ли будет конфликтовать с кем-либо еще.

Шон Перри
источник
1
Да, используйте «_», чтобы указать намерение иметь приватную функцию, но это не имеет никакого отношения к конфликтам. Любой может нуждаться в «_debug ()» или «_safe_copy ()». Если есть что-то, что помогает избежать конфликтов, это не имеет ничего общего с подчеркиванием.
Алоис Махдал
3

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

Черт, в этом не будет никаких конфликтов:

_my_foobar_method_91a3b52d990f4a9f9d5d9423ec37b64c () {
    # Custom proprietary logic protected ID 10 T intellectual property copyright clauses.
    cat <<< `echo $(xargs printf <<< "$1")`; }
}
Камило Мартин
источник
0

Как предлагается в комментарии, вы можете использовать подоболочку:

#!/bin/bash

. <(
  do_stuff() {
    local version="$1" valid='^\w+$'

    [[ "$version" =~ $valid ]] &&
      cat <<SIDE               || echo "$FUNCNAME: invalid '$version'" >&2
export FOO_${version}_X=17
export FOO_${version}_Y=42
SIDE
  }

  do_stuff 5.0 # FOO_5.0_X is "not a valid identifier"
  do_stuff 5_1
  do_stuff 5_2
)

do_keep() { :; } # just get sure the report below actually works

set | egrep '(do_|FOO_)' |  sed -e 's,^,set:\x09,'

Мы строим другой скрипт на стандартном выводе subshell для единственного побочного эффекта, который мы хотим (используя hereдокумент <<SIDE). Тогда мы с источником ..

Сила «Mise En Abime» в shявляется пугающим источником удивления.

Champignac
источник