Posts tagged: bash

ssh command-line mode and shell startup files

Apparently, if you do

ssh me@there:somepath “some cmd”

and your account is set up with ‘bash’ as your shell, only ~/.bashrc gets executed as a shell startup command

bash documentation

A great version of Bash documentation.

bash and hidden files

By default, bash inteprets ‘*’ to mean all files except those beginning with ‘.’.

If you want bash to include hidden files, then specify

shopt -s dotglob

This will include all files except ‘.’ and ‘..’. for the duration of the current shell.

If you want to include hidden files globally and permanently, add the command to the appropriate bash startup file (/etc/bashrc or ~/.bashrc).

bash indirect references

Advanced Bash-Scripting Guide – Indirect references provides a good explanation of indirect references in bash

Bash – escape sequences

How to change the title of an xterm provides a good explanation of bash escape sequences.

Bash parameter conventions

From Bash parameters and parameter expansions

Table 1. Shell parameters for functions

Parameter Purpose
0, 1, 2, … The positional parameters starting from parameter 0. Parameter 0 refers to the name of the program that started bash, or the name of the shell script if the function is running within a shell script. See the bash man pages for information on other possibilities, such as when bash is started with the -c parameter. A string enclosed in single or double quotes will be passed as a single parameter, and the quotes will be stripped.
In the case of double quotes, any shell variables such as $HOME will be expanded before the function is called. You will need to use single or double quotes to pass parameters that contain embedded blanks or other characters
that might have special meaning to the shell.
* The positional parameters starting from parameter 1. If the expansion is done within double quotes, then the expansion is a single word with the first character of the IFS special variable separating the parameters, or no
intervening space if IFS is null. The default IFS value is a blank, tab, and newline. If IFS is unset, then the separator used is a blank, just as for the default IFS.
@ The positional parameters starting from parameter 1. If the expansion is done within double quotes, then each parameter becomes a single word, so that “$@” is equivalent to “$1″ “$2″ … If your parameters are likely to contain
embedded blanks, you will want to use this form.
# The number of parameters, not including parameter 0.

Note: If you have more than 9 parameters, you cannot use $10 to refer to the tenth one. You must first either process or save the first parameter ($1), then use the shift command to drop parameter 1 and move all remaining parameters down 1, so that $10 becomes $9 and so on. The value of $# will be updated to reflect the remaining number of parameters. In practice, you will most often want to iterate over the parameters to a function or shell script, or a list created by command substitution using a for
statement, so this constraint is seldom a problem.

How a bash shell starts up under Unix and Linux

How a bash shell starts up under Unix and Linux

Interactive, login shell

Roughly speaking, an interactive login shell is what is invoked when you open up a new terminal window.

In order, the following files are loaded

/etc/profile
And first one found of ~/.bash_profile,  ~/.bash_login, ~/.profile

At exit,

~/.bash_logout

Interactive, non-login shell

Roughly speaking, an interactive, non-login shell is what you get when you type ‘bash’ or ‘su’ at the command prompt, or a file has something similar to ‘#!/bin/bash’ at the top.

An interactive, non-login shell inherits the parent shell environment.

In order, the following files are loaded

~/.bashrc

Remote shell and remote shell commands

A remote shell is one started up by rshd or ssh where you then interact at the prompt. The normal rules for an interactive, login shell apply.

In order, the following files are loaded

~/.bashrc

A remote shell command is a command similar to:

ssh me@10.1.10.123 "ls"

A remote shell command does not inherit any environment.

In order, the following files are loaded

~/.bashrc

/etc/bashrc

/etc/bashrc is not a standard part of the bash startup sequence. However, by convention, most bash distributions include something similar to

if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

either in /etc/profile or in ~/.bashrc. This loads the content of /etc/bashrc.

What do you include where?

Conventional advice says:

  • Environment settings go in /etc/profile (global) or ~/.bash_profile,  ~/.bash_login, ~/.profile (local)
  • Functions, aliases etc. go in /etc/bashrc or ~/.bashrc

As far as this goes, I agree, but it’s not complete. This incompleteness is the main reason for this note.  Remember

  • Remote shell commands do not inherit any of the custom environment settings (no parent shell!)

So, if you want a standalone ‘ssh’ command to function correctly, and see all your custom PATH settings and other environment settings, you need to ensure the environment is loaded.

What I’ve done is to bracket my environment settings in a conditional statement, and invoke them from ~/.bashrc.

# My environment file - e.g. ~/.bash_profile
if [[ ${my_environment_loaded:-false} == false ]]
then
... (set your environment here)
    my_environment_loaded=true
fi

and in ~/.bashrc, modify the standard format

if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

to something similar to

if [ -f /etc/bashrc ]; then
        . /etc/bashrc
        .  ~/.bash_profile
fi

WordPress Themes