12

I've always found bc kind of mysterious and intriguing. It was one of the original Unix programs. And it's a programming language unto itself. So I gladly take any chance I can find to use it. Since bc doesn't seem to include a factorial function, I want to define one like so:

define fact(x) {
  if (x>1) {
    return (x * fact(x-1))
  }
  return (1)
}

But … I can't then reuse that, can I? I'd want to be able to do something like

me@home$ bc <<< "1/fact(937)"
ixtmixilix
  • 13,230

2 Answers2

13

Save your function definitions in a file like factorial.bc, and then run

bc factorial.bc <<< '1/fact(937)'

If you want the factorial function to always load when you run bc, I'd suggest wrapping the bc binary with a shell script or function (whether a script or function is best depends on how you want to use it).

Script (bc, to put in ~/bin)

#!/bin/sh

/usr/bin/bc ~/factorial.bc << EOF $* EOF

Function (to put in shell rc file)

bc () {
    command bc ~/factorial.bc << EOF
$*
EOF
}

From the bc POSIX specifications:

It shall take input from any files given, then read from the standard input.

Kusalananda
  • 333,661
jw013
  • 51,212
  • Maybe you can call the file .bcrc? Can you put multiple definitions in the same file? – Bernhard Jun 29 '12 at 19:47
  • Yes you can put any valid bc syntax in the file. What you call the file and where you put it is completely up to you. – jw013 Jun 29 '12 at 20:45
  • 1
    Minor improvement: I would write exec bc (edited: exec /usr/bin/bc, see next comment) instead of bc in the wrapper script, so that the bc process substitutes to that of the script, instead of being forked (more efficient). – Maëlan Jul 30 '21 at 09:51
  • 2
    A much less minor “improvement”: in the wrapper script/function, call the original program with /usr/bin/bc (or whatever the path is) instead of bc, otherwise the wrapper keeps calling itself recursively! For the shell function, you can also do command bc. – Maëlan Jul 30 '21 at 09:55
2

Slightly better than writing a shell wrapper function for bc, you can specify the default arguments to GNU bc in an environment variable. So put a config file .bcrc or something in your home directory and then

export BC_ENV_ARGS="$HOME/.bcrc "

From the GNU bc manual:

BC_ENV_ARGS  
    This is another mechanism to get arguments to bc. The format is the same
    as the command line arguments. These arguments are processed first, so
    any files listed in the environment arguments are processed before any
    command line argument files. This allows the user to set up "standard"
    options and files to be processed at every invocation of bc. The files
    in the environment variables would typically contain function
    definitions for functions the user wants defined every time bc is run.
Kusalananda
  • 333,661