naming

why is a shell called a shell? after all it’s just a program 😀 call it program then 😀

kernel = core, shell = surrounding the core, interaction with the core.

a shell is also a runtime-environment – a program that runs scripts and programs.

a shell has a certain set of (buildin (compiled in) or external (separate file)) commands and therefore could also be regarded as programming a language.

shells

  • bash –  GNU Bourne-Again SHell of eternal recursive rebirth
  • sh – Bourne shell, the standard command language interpreter
  • ksh, ksh93 – KornShell, a command and programming language
    • Ksh is a command and programming language that executes commands read from a terminal or a file.
    • Rksh is a restricted version of the command interpreter ksh; it is used to set up login names and execution environments whose capabilities are more controlled than those of the standard shell.
    • Rpfksh is a profile shell version of the command interpreter ksh; it is used to to execute commands with the attributes specified by the user’s profiles (see pfexec(1)).
    • ksh.man.txt
  • zsh – the Z shell
    • Zsh is a UNIX command interpreter (shell) usable as an interactive login shell and as a shell script command processor.
    • Of the standard shells, zsh most closely resembles ksh but includes many enhancements.
    • Zsh has command line editing, builtin spelling correction, programmable command completion, shell
      functions (with autoloading), a history mechanism, and a host of other features.
    • zsh.man.txt
  • csh
    • csh is a command language interpreter incorporating a history mechanism (see History substitutions), job control facilities (see Jobs), interactive file name and user name completion (see File name completion), and a C-like syntax.
    • It is used both as an interactive login shell and a shell script command processor.
    • csh.man.txt

scripts and shell instances

shebang

has nothing to do with sex 😀

on top of every script there should be a line called „shebang“ which defines in what shell the script should run

#!/bin/bash

if there is no such line – it will be run in the current shell.

„#“ is called a sharp and an exclamation point – „!“ – is sometimes referred to as a bang. (!?)

Thus, shebang becomes a shortening of „sharp-bang“ (:-D)

If that is not the correct answer we could have asked Dennis Ritchie until 2011… may he rest in peace.

(src)

It is also called sha-bang,[1][2] hashbang,[3][4] pound-bang,[5] or hash-pling.[6]

google image search thinks it is a swedish band 😀 – not too bad actually 😀

return value:

any exit/return/result value other than 0 is considered an error.

you can output the return value of the last command like this:

echo $?
0

inside a script you can exit and return an exit code like this:

exit 123; # will exit program with exit code 123

sourcing:

usually a new separate sub-shell-instance is started for every started script – unless you run it like:

source /path/script.sh

. /path/script.sh

which is called „sourcing“ and means – run the script within the current shell-instance – not in a sub-shell.

You can check the PID of the current shell with

echo $$

ps uax|grep $(echo $$)

runtime variables vs shell variables

like in any programming language you can declare and use variables.

shell variables:

  • should be in $lower_case
  • scope: local shell-instance / script (no inheritance) – not accessible in sub-shell-processes
  • existance stops when script ends

environment variables:

  • are usually $IN_UPPER_CASE.
  • scope: global meaning: current shell and all sub-shells (inheritance) can read and write those variables

With the:

export variable_name

you can also make variable globally available and set a value at the same time:

export variable_name=value

The export command makes the $variable_name accessible to all sub-shell instances https://www.gnu.org/software/bash/manual/bash.html#index-export

this also works accross different shells (bash<->csh)

to create a new variable you simply go:

variable_name=value

you can delete both environment variables and shell variables with:

unset $variable_name

to output the variable’s content:

echo $variable_name

show all defined variables:

env

show all defined variables, aliases and functions:

set

set|less; # expect a lot of output

login process

An interactive login shell is started after a successful login, using /bin/login, by reading the /etc/passwd file.

This shell invocation normally reads /etc/profile and its private equivalent ~/.bash_profile upon startup. (src)

login.man.txt

The main config file of /bin/login is /etc/login.defs

login.defs.man.txt

where they come from

when adding a new user, the user’s home get’s populated with the auto-run files from

root@Debian8:~# ls -lah /etc/skel
total 32K
drwxr-xr-x   2 root root 4.0K Jun 14 12:23 .
drwxr-xr-x 115 root root  12K Jun 14 10:53 ..
-rw-r--r--   1 root root  220 Nov  5  2016 .bash_logout
-rw-r--r--   1 root root  161 Jun 14 12:23 .bash_profile
-rw-r--r--   1 root root 3.5K Nov  5  2016 .bashrc
-rw-r--r--   1 root root  675 Nov  5  2016 .profile

[user@CentOS7 ~]$ ls -lah /etc/skel;
insgesamt 24K
drwxr-xr-x.   3 root root   78 17. Mai 09:52 .
drwxr-xr-x. 111 root root 8,0K 14. Jun 11:06 ..
-rw-r--r--.   1 root root   18  2. Aug 2016  .bash_logout
-rw-r--r--.   1 root root  193  2. Aug 2016  .bash_profile
-rw-r--r--.   1 root root  231  2. Aug 2016  .bashrc
drwxr-xr-x.   4 root root   39 17. Mai 09:52 .mozilla

user@suse12:~> ls -lah /etc/skel;
insgesamt 56K
drwxr-xr-x 1 root root  254 25. Apr 14:49 .
drwxr-xr-x 1 root root 5,1K 14. Jun 12:03 ..
-rw------- 1 root root    0 18. Mai 1996  .bash_history
-rw-r--r-- 1 root root 1,2K 30. Sep 2016  .bashrc
drwxr-xr-x 1 root root    0 21. Sep 2014  bin
drwx------ 1 root root    0 21. Sep 2014  .config
-rw-r--r-- 1 root root 1,6K 11. Sep 2014  .emacs
drwxr-xr-x 1 root root    0 21. Sep 2014  .fonts
-rw-r--r-- 1 root root  19K 30. Jul 2016  .gnu-emacs
-rw-r--r-- 1 root root  305 21. Aug 2015  .i18n
-rw-r--r-- 1 root root  861 11. Sep 2014  .inputrc
drwx------ 1 root root    0 21. Sep 2014  .local
-rw-r--r-- 1 root root 6,0K 19. Aug 2016  .muttrc
-rw-r--r-- 1 root root 1,1K 30. Sep 2016  .profile
drwxr-xr-x 1 root root   20 24. Apr 12:39 public_html
-rw-r--r-- 1 root root 2,0K 21. Aug 2015  .xim.template
-rwxr-xr-x 1 root root 1,1K  3. Jun 2016  .xinitrc.template

config file run order

after login a series of script files are run…

# prepare the test:
# testing out order scripts are run during login/logout
# as root
echo 'echo "1. hello from /etc/bash.bashrc"' >> /etc/bash.bashrc; # debian8 / suse12
echo 'echo "1. hello from /etc/bashrc"' >> /etc/bashrc; # redhat / centos7
echo 'echo "2. hello from /etc/profile"' >> /etc/profile;

# as non-root user
echo 'echo "3. hello from ~/.bashrc"' >> ~/.bashrc;
echo 'echo "4. hello from ~/.profile"' >> ~/.profile;
echo 'echo "5. hello from ~/.inputrc"' >> ~/.inputrc;

echo 'echo "6. hello from ~/.bash_login"' >> ~/.bash_login;
echo 'echo "7. hello from ~/.bash_profile"' >> ~/.bash_profile;

echo 'echo "8. hello from ~/.bash_logout"' >> ~/.bash_logout;

# run the test, test results
user@Debian8:~$ uname -a; # tested with
Linux Debian8 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2 (2017-04-30) i686 GNU/Linux

user@Debian8:~$ bash -l; # simulates a login
1. hello from /etc/bash.bashrc
2. hello from /etc/profile
7. hello from ~/.bash_profile
user@Debian8:~$ logout (Shortcut/Hotkey: Ctrl+D)
8. hello from ~/.bash_logout

user@suse12:~> uname -a; # tested with
Linux suse12 4.4.21-69-default #1 SMP Tue Oct 25 10:58:20 UTC 2016 (9464f67) x86_64 x86_64 x86_64 GNU/Linux

user@suse12:~> bash -l; # simulates a login
1. hello from /etc/bash.bashrc
3. hello from ~/.bashrc
2. hello from /etc/profile
7. hello from ~/.bash_profile
user@suse12:~> logout (Shortcut/Hotkey: Ctrl+D)
8. hello from ~/.bash_logout

[user@CentOS7 ~]$ uname -a; # tested with
Linux CentOS7 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
2. hello from /etc/profile
1. hello from /etc/bashrc
3. hello from ~/.bashrc
7. hello from ~/.bash_profile
[user@CentOS7 ~]$ Abgemeldet (Shortcut/Hotkey: Ctrl+D)
8. hello from ~/.bash_logout

debian8 and suse12 run /etc/bash.bashrc

redhat / centos7 run /etc/bashrc instead.

also:

as you can see ~/.bash_login is not run at all, because it is only run if ~/.bash_profile does NOT exist

# so let's remove ~/.bash_profile and rerun the test again
rm ~/.bash_profile

user@Debian8:~$ uname -a; # tested with
Linux Debian8 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2 (2017-04-30) i686 GNU/Linux
user@Debian8:~$ bash -l; # simulates a login
1. hello from /etc/bash.bashrc
2. hello from /etc/profile
6. hello from ~/.bash_login
user@Debian8:~$ logout
8. hello from ~/.bash_logout

user@suse12:~> uname -a; # tested with
Linux suse12 4.4.21-69-default #1 SMP Tue Oct 25 10:58:20 UTC 2016 (9464f67) x86_64 x86_64 x86_64 GNU/Linux
user@suse12:~> bash -l; # simulates a login
1. hello from /etc/bash.bashrc
3. hello from ~/.bashrc
2. hello from /etc/profile
6. hello from ~/.bash_login
user@suse12:~> logout
8. hello from ~/.bash_logout

[user@CentOS7 ~]$ uname -a; # tested with
[user@CentOS7 ~]$ bash -l; # simulates a login
2. hello from /etc/profile
6. hello from ~/.bash_login

this pretty much ruins the day on centos7…

suse12 and debian do not use this config per default.

you may also have noted – that ~/.profile is not run at all.

it is only run if neither ~/.bash_login nor ~/.bash_profile exist.

so let’s remove ~/.bash_login – and rerun the test.

rm ~/.bash_login

user@Debian8:~$ uname -a; # tested with
Linux Debian8 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2 (2017-04-30) i686 GNU/Linux
user@Debian8:~$ bash -l; # simulates a login
1. hello from /etc/bash.bashrc
2. hello from /etc/profile
3. hello from ~/.bashrc
4. hello from ~/.profile
user@Debian8:~$ logout
8. hello from ~/.bash_logout

user@suse12:~> uname -a; # tested with
Linux suse12 4.4.21-69-default #1 SMP Tue Oct 25 10:58:20 UTC 2016 (9464f67) x86_64 x86_64 x86_64 GNU/Linux
user@suse12:~> bash -l; # simulates a login
1. hello from /etc/bash.bashrc
3. hello from ~/.bashrc
2. hello from /etc/profile
4. hello from ~/.profile
user@suse12:~> logout
8. hello from ~/.bash_logout

[user@CentOS7 ~]$ uname -a; # tested with Linux CentOS7 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 
bash -l; # simulates a login
2. hello from /etc/profile
4. hello from ~/.profile

functions:

in bash programming – you can do functions.

so while logged in as non-root user you could:

vi .bashrc; # edit this file and at the very end, add those lines

function ws_info() {
 echo -e "\n Machine info:"; uname -a
 echo -e "\nLogged in users: "; who
 echo -e "Uptime: "; uptime
}


ESC :x # save quit

bash -l; # if you now simulate a login

# you will realize you can call the function ws_info simply by typing
ws_info

Machine info:
Linux Debian8 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2 (2017-04-30) i686 GNU/Linux

Logged in users:
user     :0           2017-06-14 10:53 (:0)
user     pts/0        2017-06-14 12:03 (172.20.0.7)
Uptime:
 12:17:49 up 14 min,  2 users,  load average: 0.57, 0.48, 0.35

Videos:

Links:

http://dwaves.de/2017/06/13/105-2-customize-or-write-simple-scripts-exit-codes-error-signal-handling-while-for-loop-if-then-else-test-file-exists/

https://www.computerworld.com.au/article/279011/-z_programming_languages_bourne_shell_sh?fp=&fpid=&pf=1

http://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html

LPIC-1 102 105.1 Customize and use the shell environment

admin