Bagaimana saya bisa membuat fungsi lokal di bashrc saya?

40

Bashrc saya. Memiliki beberapa kode yang berulang sehingga saya menggunakan fungsi untuk menyederhanakannya

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

do_stuff '5.1'
do_stuff '5.2'

Namun, sekarang ketika saya menggunakan shell saya, nama "do_stuff" ada di dalam ruang lingkup sehingga saya bisa melengkapi dan menjalankan fungsi itu (berpotensi mengacaukan variabel lingkungan saya). Apakah ada cara untuk membuat "do_stuff" hanya terlihat di dalam .bashrc?

hugomg
sumber
2
Jika Anda tidak melihat ekspor, Anda juga dapat menggunakan ()untuk membuat subkulit. Kemungkinan lain untuk kasus-kasus sederhana adalah menggunakan for version in 5.1 5.2loop, meskipun ini memungkinkan versionmelarikan diri.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

40

Gunakan unsetsebagai baris terakhir di .bashrc:

unset -f do_stuff

akan menghapus / membatalkan fungsi do_stuff.

Untuk menghapus / menghapus variabel, jalankan variabel sebagai berikut:

unset variablename
kekacauan
sumber
Apakah tidak disetel benar-benar satu-satunya jalan di sini? Yah, saya kira jika saya menggunakan nama yang sangat panjang dan jelek untuk fungsi saya kesempatan itu berbenturan dengan sesuatu yang lain tidak akan sebesar itu ...
hugomg
Jika itu masalah cek frist jika fungsi tersebut ada: if type do_stuff >/dev/null 2>&1; then echo "exists"; else echo "dont"; fi.
kekacauan
8
Ini tidak akan berfungsi jika do_stuffdigunakan di dalam fungsi lain. Ketika Anda memanggil fungsi itu, Anda akan mendapatkannya bash: do_stuff: command not found. Saya tahu ini bukan kasus yang tepat yang dibicarakan oleh op, tetapi perlu ditunjukkan.
Burhan Ali
Bagus dan POSIX .
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
15

Opsi lainnya adalah menggunakan garis bawah seperti dalam bahasa skrip lain untuk menunjukkan Anda tidak bermaksud agar fungsi ini menjadi publik. Kemungkinan Anda mengetik _do_foo cukup kecil dan juga tidak akan bertentangan dengan orang lain.

Sean Perry
sumber
1
Ya, gunakan "_" untuk menunjukkan niat memiliki fungsi pribadi, tetapi ini tidak ada hubungannya dengan konflik. Siapa pun dapat membutuhkan "_debug ()" atau "_safe_copy ()". Jika ada sesuatu yang membantu menghindari konflik, itu tidak ada hubungannya dengan garis bawah.
Alois Mahdal
3

Satu-satunya solusi yang bisa saya pikirkan adalah menggarisbawahi dan memberinya nama yang cukup unik, bahkan mungkin menamainya dengan titik-titik seperti bahasa fancypants ( tapi ini tidak akan bekerja di kamu dulush ).

Heck, ini tidak akan memiliki konflik:

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

Seperti yang disarankan dalam komentar, Anda dapat menggunakan subkulit:

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

Kami membuat skrip lain di atas output standar subkulit untuk satu-satunya efek samping yang kami inginkan (menggunakan heredokumen <<SIDE). Lalu kami sumber dengan. .

Kekuatan 'mise en abime' in shadalah sumber keajaiban yang menakutkan.

Champignac
sumber