5

I am developing a script that will configure and setup an ubuntu-desktop environment. One of the changes it makes is appending functions and other things to the ~/.bashrc file. Later in the script, I need to call one of the functions added to ~/.bashrc but I get the command not found error. Here is an example script:

# t.sh
#!/bin/bash

text='test-func() { echo It works!; }'
echo "$text" >> ~/.bashrc

source ~/.bashrc
test-func

echo checkpoint

Output:

./t.sh: line 10: test-func: command not found
checkpoint

I assumed sourcing ~/.bashrc would update the shell allowing me to call test-func but it does not. Googling around I found exec bash to replace source ~/.bashrc.

New Output:

./t.sh: line 10: test-func: command not found

From my understanding of exec, it just creates a new shell cutting the script off; therefore "checkpoint" is never printed out.

How can I update ~/.bashrc and run the updates in the same script?

Any help is much appreciated.

Nelson
  • 153
  • 1
  • 1
  • 5
  • and what if you try a random file.txt instead of .bashrc ? – Sergiy Kolodyazhnyy Mar 25 '17 at 10:34
  • @Serg What do you mean by use a text file? The purpose of using ~/.bashrc is to be able to call the function. – Nelson Mar 25 '17 at 10:39
  • Have you tried giving the full path instead of the ~/ ? – Julen Larrucea Mar 25 '17 at 10:48
  • @Nelson see Malte's answer. My suspicion was exactly what he describes - ~/.bashrc has a way of detecting if the shell is running non-interactively ( i.e. when you are running a script ) and will quit without executing your definitions ( that's what sourcing a file does - it "executes" the definitions ). You will need to have a separate file for defining your functions, if you want them to be sourced both from within ~/.bashrc AND from a script – Sergiy Kolodyazhnyy Mar 25 '17 at 10:54
  • I don't think that's the issue as this scenario has also played out the same using $HOME instead of ~ but I tested it anyways and it does the same thing – Nelson Mar 25 '17 at 10:55

1 Answers1

5

Actually, your .bashrc does get sourced. However, .bashrc is intended to be read by interactive shells. A shell that runs a script is not interactive.

In Ubuntu, .bashrc checks that the shell sourcing it is interactive, and otherwise stops execution. You should find this line towards the beginning:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

This causes your script to stop sourcing the file before it reads your function.

You can simply attach your function to another file than .bashrc and it should work fine. If you insist on using .bashrc, you could simply set the variable PS1 to some dummy value in your script before sourcing .bashrc.

Malte Skoruppa
  • 13,196
  • 5
  • 57
  • 65
  • 1
    In fact, it's a frequent practice to have separate files for aliases and function definitions. Good answer – Sergiy Kolodyazhnyy Mar 25 '17 at 10:56
  • I do insist on using ~/.bashrc because I wish to intend on using the functions in the terminal as well as later in the mentioned script. I looked through as well as searched the ~/.bashrc file and that line of code is not there. Just to be sure I set PS1=false at the very top of the file. This had no effect. – Nelson Mar 25 '17 at 10:58
  • @Nelson Can you post your .bashrc to Pastebin? – Malte Skoruppa Mar 25 '17 at 11:00
  • To move my aliases and functions to a separate file, would I just source the separate file in ~/.bashrc? – Nelson Mar 25 '17 at 11:00
  • @Nelson Well, again, as I mentioned - frequent practice is to source ~/.bash_functions file from both within a script when you need and from ~/.bashrc That way you can simply update that file, and it will work for both interactive and non-interactive sessions – Sergiy Kolodyazhnyy Mar 25 '17 at 11:00
  • I agree with Serg, a separate file is a much cleaner way of handling things than tricking a non-interactive shell into sourcing your .bashrc. :-) – Malte Skoruppa Mar 25 '17 at 11:03
  • 2
    Thank you @MalteSkoruppa and @Serg for your very helpful input! I have moved all of my .bashrc additions to a separate file out of OCD with code and file neatness, and it solves my problem. I can create, source, then call the .bash_functions file in the same script. – Nelson Mar 25 '17 at 11:16