Cara menentukan nama fungsi dari dalam suatu fungsi


163

Jika saya memiliki skrip Bash seperti:

#!/bin/bash

f() {
  # echo function name, "f" in this case
}

Apakah ada cara untuk melakukan ini? Ini dapat digunakan dalam pesan bantuan seperti

printf "Usage: %s: blah blah blah \n" $(basename $0) >&2; 

Hanya dalam hal ini yang saya inginkan bukan $0, yang merupakan nama file dari skrip.


2
Terkait: Bash logging framework yang menggunakan FUNCNAMEarray dan variabel Bash lainnya: github.com/codeforester/base/blob/master/lib/stdlib.sh . Lihat fungsi log_debug_enterdan log_debug_leavekhususnya.
codeforester

Jawaban:


236

Anda dapat menggunakan ${FUNCNAME[0]}di bashuntuk mendapatkan nama fungsi.


79

Dari Manual Referensi Bash :

FUNCNAME

Variabel array yang berisi nama-nama semua fungsi shell saat ini dalam tumpukan panggilan eksekusi. Elemen dengan indeks 0 adalah nama dari setiap fungsi shell yang sedang dijalankan. Elemen terbawah (yang memiliki indeks tertinggi) adalah "utama". Variabel ini hanya ada ketika fungsi shell mengeksekusi. Tugas untuk FUNCNAME tidak berpengaruh dan mengembalikan status kesalahan. Jika FUNCNAME tidak disetel, FUNCNAME akan kehilangan properti khususnya, bahkan jika kemudian disetel ulang.

Variabel ini dapat digunakan dengan BASH_LINENO dan BASH_SOURCE. Setiap elemen FUNCNAME memiliki elemen yang sesuai di BASH_LINENO dan BASH_SOURCE untuk menggambarkan tumpukan panggilan. Misalnya, $ {FUNCNAME [$ i]} dipanggil dari file $ {BASH_SOURCE [$ i + 1]} di nomor baris $ {BASH_LINENO [$ i]}. Penelepon bawaan menampilkan tumpukan panggilan saat ini menggunakan informasi ini.

Ketika bash array diakses tanpa indeks, elemen pertama dari array akan dikembalikan, sehingga $FUNCNAMEakan bekerja dalam kasus-kasus sederhana untuk memberikan nama fungsi segera saat ini, tetapi juga mengandung semua fungsi lain di tumpukan panggilan. Sebagai contoh:

# in a file "foobar"
function foo {
    echo foo
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

function foobar {
    echo "$(foo)bar"
    echo "In function $FUNCNAME: FUNCNAME=${FUNCNAME[*]}" >&2
}

foobar

Akan menghasilkan:

$ bash foobar
In function foo: FUNCNAME=foo foobar main
foobar
In function foobar: FUNCNAME=foobar main

6
Saya masih belum mengerti. Mengapa menambahkan [0]jika itu tersirat dengan mengakses variabel yang tidak didekorasi?
Tom Hale

15
Karena itu menipu dan tidak mengetahui tipe aktual variabel? Tentu, itu tidak selalu diperlukan, tetapi seperti banyak bash-isme lainnya, ini adalah konvensi yang malas. Lebih baik bersikap eksplisit daripada mendua.
bschlueter

36

Saya gunakan ${FUNCNAME[0]}untuk mencetak nama fungsi saat ini


@ bschlueter tetapi ketika Anda mereferensikan sebuah array tanpa memperlakukannya seperti sebuah array di Bash, ia hanya mencetak nilai pertama; oleh karena itu, bagaimana jawaban yang diterima salah?
Alexej Magura

4
Tentu, dan itu nyaman, tetapi mengerikan untuk perawatan dan pengujian. Jangan malas, jelaskan.
bschlueter

1

Contoh lain:

# in a file "foobar"
foo() {
    echo "$FUNCNAME fuction begins"
}

foobar() {
    echo "$FUNCNAME fuction begins"
}

echo 'begin main'
foo
foobar
echo 'end main'

Akan menghasilkan:

begin main
foo fuction begins
foobar fuction begins
end main

-1

Cara paling sederhana untuk mendapatkan nama fungsi (dari dalam suatu fungsi)

echo $0

Tolong berhenti menyalahgunakan ###jawaban Anda.
Marcin Orlowski

@MarcinOrlowski Apakah Anda baik-baik saja? Sepertinya Anda bisa menggunakan pelukan.
jasonleonhard
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.