-1

Let's say I have a script:

#!/bin/bash
whoami

I would like to have it so that when I execute this script, foo is always printed before its execution. In fact, I would want foo to be printed before execution of any script (not just this example).

I tried playing around with the bashrc file however this doesn't seem to work:

case $- in
    *i*) echo "foo";;
      *) return;;
esac
Chris Davies
  • 116,213
  • 16
  • 160
  • 287
Foo
  • 232
  • 2
    echo foo in the script would print foo, but this would not be "before execution". Please make sure there is no XY problem here. [Edit] the question if there is. Why do you need foo to be printed before actual execution? Before execution of any script? or before execution of this exact script only? – Kamil Maciorowski Mar 02 '24 at 14:25
  • @KamilMaciorowski I essentially want to run a custom bit of code before any script is executed (specifically, I want to set a trap) – Foo Mar 02 '24 at 14:39
  • Do you really want non-interactive or did you mean interactive? Bashrc is not read by non-interactive shells (unless you have explicitly set .profile to source it, as is the case in Debian and its derivatives), and the code you show would echo foo only in interactive shells since you're looking for i in $_. And what do you mean by "before any script"? What's a script? Shell scripts only? Perl? Python? – terdon Mar 02 '24 at 14:45
  • @terdon yes, non-interactive. And only shell scripts – Foo Mar 02 '24 at 15:17
  • @Foo which shells? Bash? Sh? Zsh? Tcsh? Csh? Fish? All users? Specific users? What of system calls launched by other scripts? If a perl or python script runs an sh command, for example? And you really want to exclude non interactive shells that are running anything other than a shell script? Please edit your question and give more context. Your OS will also likely be relevant. – terdon Mar 02 '24 at 15:46
  • @terdon just bash scripts – Foo Mar 02 '24 at 15:51
  • 1
    Please EDIT your question and add all these details. It will be very, very complicated to do this only for bash, and we still need to know if this should also happen when bad is called by another program. If you explain why you want this, what you are really trying to achieve, that would make it easier to answer. – terdon Mar 02 '24 at 15:59
  • 1
    As others have said, can you edit your question to explain why you want to do this. It sounds a good way to break your system. For example lsb_release tells you various information about your system. Installers can run it to help decide what to do based on its output. If you have an implementation in bash, and it now outputs an unexpected foo then installation scripts are going to be confused, and may do the wrong thing. – icarus Mar 02 '24 at 19:10

1 Answers1

2

~/.bashrc is only interpreted by non-login interactive invocations of bash not running in posix mode¹

For a file that is interpreted by every invocation of bash (excluding ones running in posix mode), you can use $BASH_ENV:

$ cat ~/.bashenv
if [[ $- != *i* ]]; then
  echo foo
fi
$ export BASH_ENV=~/.bashenv
$ bash -c 'echo bar'
foo
bar

If that echo foo is only meant to be interpreted by bash scripts, that is when bash is invoked as bash /path/to/file (like with a #! /bin/bash shebang or the more correct #! /bin/bash - form) and not other forms of non-interactive shell invocations (like bash -c code (as done by xterm, vi, GNU parallel... when running $SHELL code), or bash < file) you can change the [[ $- != *i* ]] to [[ $- != *[ics]* ]].

The equivalent for zsh is ~/.zshenv (or $ZDOTDIR/.zshenv).

All csh/tcsh invocations read ~/.cshrc (~/.tcshrc) unless passed -f (which is why most csh scripts have a #! /bin/csh -f shebang).

ksh used to honour $ENV but that was stopped for non-interactive shells for security reasons ($ENV processing for interactive invocations is still a POSIX requirement for sh and the only way to have a shell customisation file there).


¹ Like when invoked as sh or when there's $POSIXLY_CORRECT or SHELLOPTS=posix in the environment or if called wih -o posix. ~/.bashrc may also be interpreted by bash shells when invoked even non-interactively over ssh with some builds of bash. bash startup file processing is a bit of a mess.