Come posso creare una funzione locale nel mio bashrc?


40

Il mio .bashrc aveva del codice ripetitivo, quindi ho usato una funzione per semplificarlo

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

do_stuff '5.1'
do_stuff '5.2'

Tuttavia, ora quando uso la mia shell il nome "do_stuff" rientra nell'ambito, quindi posso completare la scheda ed eseguire quella funzione (potenzialmente incasinando le mie variabili di ambiente). C'è un modo per rendere "do_stuff" visibile solo all'interno di .bashrc?


2
Se non è stata necessaria l'esportazione, è possibile utilizzare anche ()per creare una subshell. Un'altra possibilità per i casi semplici è l'utilizzo di un for version in 5.1 5.2ciclo, sebbene ciò permetta di versionscappare.
Ciro Santilli 9 改造 中心 法轮功 六四 事件

Risposte:


40

Usa unsetcome ultima riga nel tuo .bashrc:

unset -f do_stuff

cancella / disattiva la funzione do_stuff.

Per cancellare / disinserire le variabili invocarlo come segue:

unset variablename

Unset è davvero l'unico modo qui? Beh, immagino che se uso un nome davvero lungo e brutto per la mia funzione, la possibilità che si scontrano con qualcos'altro non sarà così grande ...
hugomg

Se questo è il controllo Frist problema se la funzione esiste: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
caos,

8
Questo non funzionerà se do_stuffviene utilizzato all'interno di un'altra funzione. Quando chiami quella funzione, otterrai bash: do_stuff: command not found. So che questo non è il caso esatto di cui parlava l'operazione, ma vale la pena sottolineare.
Burhan Ali,


15

L'altra opzione è utilizzare i trattini bassi come in altre lingue con script per indicare che non si intende che questa funzione sia pubblica. La probabilità che tu digiti _do_foo è piuttosto piccola e difficilmente entrerà in conflitto con qualcun altro.


1
Sì, usa "_" per indicare l'intenzione di avere una funzione privata, ma questo non ha nulla a che fare con i conflitti. Chiunque può aver bisogno di "_debug ()" o "_safe_copy ()". Se c'è qualcosa che aiuta a evitare i conflitti, non ha nulla a che fare con le sottolineature.
Alois Mahdal

3

L'unica soluzione che mi viene in mente è di sottolinearlo e dargli un nome piuttosto singolare, magari anche spaziandolo con punti come un linguaggio fantasioso ( ma questo non funzionerà in voi vecchish ).

Diamine, questo non avrà alcun conflitto:

_my_foobar_method_91a3b52d990f4a9f9d5d9423ec37b64c () {
    # Custom proprietary logic protected ID 10 T intellectual property copyright clauses.
    cat <<< `echo $(xargs printf <<< "$1")`; }
}

0

Come suggerito in un commento, è possibile utilizzare una subshell:

#!/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,'

Costruiamo un altro script sull'output standard di subshell per l'unico effetto collaterale che desideriamo (usando il heredocumento <<SIDE). Quindi fonte con ..

Il potere di "mise en abime" shè una fonte spaventosa di meraviglia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.