3

I use zsh (sometimes bash). The thing is that I have multiple shell scripts and I've got no idea how to code a small function for printing function code by it's name (with highlighting; I use pygmentize -g). Here's a small example of what I want to get:


$ getfunc "somefunc"

# from    my_little_hacks.sh
somefunc () {
    # function code
}

Is it a clean and efficient way to do it in shell or awk without using nl and cat in the best time available for shell interpreter?

It is improbable for a function to have a word function in it's body except for when there are nested ones there. It is also next to impossible that it has a { or } legally unpaired inside the quotes.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
theoden8
  • 773
  • 7
  • 16
  • 3
    As an aside, using the `function` keyword is bad form -- makes your code incompatible with POSIX sh without adding any benefit. – Charles Duffy Jul 08 '15 at 23:54
  • @CharlesDuffy didn't know, thanks. – theoden8 Jul 08 '15 at 23:58
  • On a different note -- http://mywiki.wooledge.org/DontReadLinesWithFor – Charles Duffy Jul 09 '15 at 00:01
  • Also, you should declare `M` local -- it's a global variable, and is changed whenever your function is called. – Charles Duffy Jul 09 '15 at 00:03
  • Also, why grep the output of `awk`, rather than asking awk to filter for lines containing the string VERSION and exit after the first match? – Charles Duffy Jul 09 '15 at 00:04
  • @CharlesDuffy , I was using this answer to get it all work really clean: http://stackoverflow.com/a/30671631/4811285 – theoden8 Jul 09 '15 at 00:07
  • Understood; my point is that that answer is... less than optimal, in terms of how it's written. – Charles Duffy Jul 09 '15 at 00:07
  • @CharlesDuffy besides, noone would use a variable of 1 letter (i j k m a b n etc.) – theoden8 Jul 09 '15 at 00:08
  • Single-letter variable names are used all the time. `i` in particular -- it's **the** standard name to give a counter, and it's a common convention to increment to the next letter when nesting. – Charles Duffy Jul 09 '15 at 00:08
  • It's also a little ironic to say "no-one would use a variable of 1 letter" when discussing a function you provided which uses variables whose names have only one letter. :) – Charles Duffy Jul 09 '15 at 00:25
  • @CharlesDuffy this is more into philosophy. I meant to say that no program should crutch on a one-letter variable. – theoden8 Jul 09 '15 at 00:33
  • @CharlesDuffy deleted cpanlist in the post for your mercy. I dont think you should worry not :) – theoden8 Jul 09 '15 at 00:56
  • 1
    Doesn't that most recent edit invalidate the question entirely? Since it *is* the answer at this point? Should that be rolled back? – Etan Reisner Jul 09 '15 at 01:55
  • @EtanReisner i think it's fully illustrates what I want. Moreover, it shows the valid answer sooner than as you get to the first reply. In my personal it does not invalidate the question. You see what is asked and what is answered. Like post-editing made in many others. – theoden8 Jul 09 '15 at 11:02
  • 1
    You subsumed the answer into the post. That makes the answer wrong as it doesn't provide any new information. It also makes the question pointless as it now no longer even has a question to ask. The fact that the comments push the answer down is solved by the default collapsing and can be further helped if the people delete their (at this point) useless comments (something that I believe should generally be done though I don't know what the official position on that is). – Etan Reisner Jul 09 '15 at 13:37
  • @EtanReisner, k. changed for the sake of comprehension. – theoden8 Jul 09 '15 at 14:14

1 Answers1

6
declare -f funcname

...will retrieve the code for function funcname in both bash and zsh. Thus:

getfunc() {
  declare -f "$@" | pygmentize -l bash
}
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 2
    damn, this is one of the moments when you realize that all you need is already written, and you just have to search.. – theoden8 Jul 08 '15 at 23:59
  • Great idea on the pipe through pygments! I also use `declare` often enough that I had made `fn` a simple alias to `declare -f`, but will switch it to a function to enable the pipe. – Micah Elliott Jul 09 '15 at 00:26