4

I'm trying to create a global counter variable to see how many times ~/.profile gets executed. Thus:
In ~/.bashrc:

# ... 
if [ "$PROFILE_EXEC_TIMES" = "" ]; then
 export PROFILE_EXEC_TIMES=0
fi
let "PROFILE_EXEC_TIMES += 1"

In ~/.profile:

# ... 
export PROFILE_EXEC_TIMES
let "PROFILE_EXEC_TIMES += 1"

But when I open a new shell and write echo $PROFILE_EXEC_TIMES, all I get is 1. $PROFILE_EXEC_TIMES must be at least 2. I suspect that ~/.profile isn't sourced by bash... if so, what I need to do in order to check how many times ~/.profile is executed?


Edit:
I've noticed that /etc/gdm/Xsession is sourcing ~/.profile by the following line:

test -f "$HOME/.profile" && . "$HOME/.profile"

and ~/.bashrc is sourced in ~/.profile by the following lines:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

Also, I've add the following line to ~/.bashrc & ~/.profile:

echo $(cd ${0%/*} && echo $PWD/${0##*/}) >> /home/myUserName/a

and could see that only one line was added to the file after I logged in to my user.

I want to emphasize that my goal here is:
Finding out how many times ~/.profile is executed when user logs in.

Additional details:

$ uname -a
Linux my-desktop 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:52:42 UTC 2010 x86_64 GNU/Linux
$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.1 LTS"
1
  • 1
    It should only execute once per login. And using an environment variable is not a reliable way to count it. Environment variables are inherited by processes forked from the process that adds them. They will not automatically be available to all processes on the system. Use a file to keep count instead. E.g.: date >> /tmp/profile_runs. Then you can count the number of lines that has bee appended. wc -l < /tmp/profile_runs.
    – geirha
    Feb 3, 2011 at 23:08

5 Answers 5

6

From your comments on my original answer, it appears that your real question is "Is ~/.profile sourced by GNOME?" The answer is yes. Look in /etc/gdm/Xsession:

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Original Answer

From the manpage of bash:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

So you may have a file called .bash_profile or .bash_login in your home directory. If either of these exists, bash will use it instead of .profile.

6
  • Sorry but the info you supplied doesn't help.
    – Dor
    Nov 13, 2010 at 22:24
  • Are you sure that you are invoking bash as an interactive login shell? You should edit your question to explain how you are invoking bash. Nov 13, 2010 at 23:11
  • I'm not invoking bash, it is automatically invoked by some startup script of my Ubuntu 10.04 desktop, when I login to my user.
    – Dor
    Nov 13, 2010 at 23:46
  • What kind of login? Are you logging into a Terminal? Into GNOME? Into KDE? Into some other desktop? Nov 16, 2010 at 2:52
  • When I logging into GNOME.
    – Dor
    Dec 7, 2010 at 12:34
2

First, if you want to watch what's going on in a shell script, put set -x at the top (just after the #! line if any). This prints a trace of the execution on standard error. Here the shell's standard error should be redirected to ~/.xsession-errors.

There's a contradition in your question: you say your goal is “finding out how many times ~/.profile is executed when user logs in”, and then you go on to hack with .bashrc. Merely putting export PROFILE_EXEC_TIMES; let "PROFILE_EXEC_TIMES += 1" in your .profile does count how many times it's sourced, and it's unsurprising that the result is 1 (you only log in once).

Your .profile sources .bashrc, which is weird as .profile is used when logging in and .bashrc is the configuration file of bash when it's interactive. Maybe you did this to work around a design bug in bash, whereby it doesn't read .bashrc in a shell that is both a login shell and interactive; I prefer to have a .bash_profile that sources both .profile and (if the shell is interactive) .bashrc.

Note that your .profile takes care not to source .bashrc if the shell isn't bash. This explains why .bashrc isn't read when you log in: /etc/gdm/Xsession is executed by /bin/sh, which on Ubuntu 10.04 is dash, not bash.

Near the top of .bashrc, you have: “If not running interactively, don't do anything” commenting the line [ -z "$PS1" ] && return. Actually, that line won't do this; it's fairly common for PS1 to be set in non-interactive shells (for example, it's set by /etc/profile). A reliable test for an interactive bash is [[ $- = *i* ]].

You may also be interested in Difference between .bashrc and .bash_profile.

7
  • (#1) I think that there's no contradiction, since bash (or the startup script) has many tricky peculiarities that may causing the problem. (#2) When adding the snippet that increment $PROFILE_EXEC_TIMES to .bashrc (and NOT to .profile), I still get 1 when echo'ing that variable via a new terminal. (#3) I didn't intentionally sourced .profile from .bash. I didn't change anything in .bashrc nor in .profile, except for the snippet that increments $PROFILE_EXEC_TIMES.
    – Dor
    Nov 19, 2010 at 7:35
  • @Dor: The contradiction is between what you claim you want to find out (“finding out how many times ~/.profile is executed when user logs in”) and your next sentence where you mention modifying ~/.bashrc. Why not put different traces in ~/.profile and ~/.bashrc if you want to understand what's going on? Add a time to the traces (date >>/tmp/${0##*/}.log) and wait a second between logging in and starting a terminal to distinguish between what happens when you log in and what happens when you start a terminal. Nov 19, 2010 at 20:28
  • @Dor: Regarding #3, I know the oddities such as sourcing .bashrc from .profile or the flawed test for an interactive shell aren't from you; they're not even from Ubuntu as they're also in Debian. But if you want to understand what's going on, these are things you need to know. Nov 19, 2010 at 20:33
  • I've add the code that you wrote to both .bashrc & .profile and the result is one file called Xsession.log with the following single line: Sun Nov 21 21:12:45 IST 2010
    – Dor
    Nov 21, 2010 at 19:21
  • @Dor: Sounds right: /etc/gdm/Xsession sources ~/.profile. I've lost track: is there still something you don't understand? Nov 21, 2010 at 20:25
2

@Dor: I dont have enough reputation yet to write comments, but i can answer you last comment from Dec 7 '10 at 12:41, which was:

"When I append the code to both files & log into GNOME, there's still a single line in the file Xsession.log (the file Xsession.log is empty before each logon). Why's that? There should be at least two lines in the latter case."

No, because when you logon in Gnome (using GDM), ~/.bashrc is NOT executed, only ~/.profile. As explained by Gilles, Gnome calls /etc/gdm/Xsession, which in turn sources ~/.profile. And ~/.profile ONLY sources ~/.bashrc if running bash.

From ~/.profile:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

And when you login in Gnome/GDM, you are not using Bash, because, as Gilles also pointed out, /etc/gdm/Xsession has uses the directive #! /bin/sh, which in Ubuntu is a symlink to dash, not bash.

So the whole Gnome login process does not invoke bash. That why files like /etc/profile, ~/.bash_login, ~/.bash_profile are not automatically called. Thats why /etc/profile and ~/.profile had to be "manually", explicitly sourced by /etc/gdm/Xsession. And they both test for Bash before sourcing ~/.bashrc

The test on "is interactive shell" in /etc/profile (and also on ~/.bashrc) may be flawed, but the bash test works, and it return false when logging in. Thats why your log file has only 1 line... thats from ~/.profile

When you open a terminal, its a bash terminal. Bash itself calls ~/.bashrc directly, and ~/.profile is not executed.

I hope now everything has cleared up.

Last but not least: Do not source ~/.profile from ~/.bashrc, as suggested by previous answer. That will cause a circular reference (both files source each other), and is both technically and conceptualy wrong. It may cause problemns if bash is ever used for login (maybe text mode, repair console?)

0

~/.profile is only executed for login shells (bash --login), not all shells, thats what ~/.bashrc is for. So the count of 1 should be correct, as ~/.profile is executed once when you login.

If you don't trust the environment variable counter just write a file with a unique filename (something like $(uuidgen)) to keep track of the ~/.profile executions.

1
  • But please do notice that I incremented the counter in both files. So when ~/.bashrc is executed, the counter equals 1, afterwards ~/.profile is executed, thus the counter equals 2 (at least).
    – Dor
    Nov 13, 2010 at 23:01
0

Are you sourcing .profile in .bashrc? If not, Bash won't read it. You should have something like this, probably best placed at the top of your .bashrc:

[ -r ${HOME}/.profile ] && . ${HOME}/.profile

That will make sure that .profile both exists and is readable, and if it is than process it.

2
  • I have the following line in /etc/gdm/Xsession: test -f "$HOME/.profile" && . "$HOME/.profile". See my edit please.
    – Dor
    Nov 14, 2010 at 6:59
  • No, do not source .profile from .bashrc. The other way around is ok, and common. See mywiki.wooledge.org/DotFiles
    – geirha
    Feb 3, 2011 at 23:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .