Как я могу создать локальную функцию в моем 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?


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. Я знаю, что это не тот случай, о котором говорил опер, но на это стоит обратить внимание.
— Бурхан Али


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является пугающим источником удивления.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.