Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a sourced bash snippet conditionally provide a function to the sourcing shell?

Tags:

include

bash

Is it possible to source a Bash snippet, but only actually provide a function from inside it if a certain condition holds true?

So what I am asking is that I can unconditionally source all files from a directory, but the sourced files contain the logic to provide functions to the sourcing shell or not.

Example:

  • .bashrc sources whole sub folder .bashrc.d
  • .bashrc.d/xyz provides a function adduser2group which works on old systems where usermod doesn't handle -a -G
  • .bashrc.d/xyz should provide that function only to the sourcing shell if it's running on such old system.

My current method is to conditionally create an alias named adduser after the Debian program (alias adduser=adduser2group). So I only implement the adduser <user> <group> semantics, but still it's helpful.

Is there a solution that doesn't require this workaround? After all this method means a chance for name clashes which I'd prefer to avoid.

like image 315
0xC0000022L Avatar asked Jan 22 '13 16:01

0xC0000022L


People also ask

What is the purpose of conditional expressions in shell scripts?

Conditions in Shell Scripts This essentially allows us to choose a response to the result which our conditional expression evaluates to.

How does source work in bash?

The source Command The built-in bash source command reads and executes the content of a file. If the sourced file is a bash script, the overall effect comes down to running it. We may use this command either in a terminal or inside a bash script.

What happens when you source a file in bash?

The source command reads and executes commands from the file specified as its argument in the current shell environment. It is useful to load functions, variables, and configuration files into shell scripts.


2 Answers

You can use standard shell logic to control whether functions are defined are not.

lib.sh:

if true; then
    foo() {
        echo foo
    }
else
    bar() {
        echo bar
    }
fi

test:

#!/bin/bash

. ./lib.sh
foo
bar

When running it, only foo is defined:

$ bash test
foo
test: line 5: bar: command not found

Substitute if true with more appropriate logic for your application…

like image 104
andrewdotn Avatar answered Oct 27 '22 04:10

andrewdotn


You can define the functions you want and, whenever a particular condition holds, you just unset the function:

$ function alpha() { echo $1; }
$ alpha 10
10

Evaluating your condition -- and considering it holds true:

$ if [[ your condition ]]; then unset alpha; fi
$ alpha 10
alpha: command not found
like image 35
Rubens Avatar answered Oct 27 '22 05:10

Rubens