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
- written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell.[7][8] First released in 1989,[9] it has been distributed widely as the default login shell for Linux distributions and Apple’s macOS (formerly OS X). A version is also available for Windows 10.[10]
- downward-compatible to sh shell
- bash.man.txt
- sh – Bourne shell, the standard command language interpreter
- written by Stephen Bourne
- predecessor of bash
- sh.man.txt
- 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]
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)
The main config file of /bin/login is /etc/login.defs
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://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html
liked this article?
- only together we can create a truly free world
- plz support dwaves to keep it up & running!
- (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
- really really hate advertisement
- contribute: whenever a solution was found, blog about it for others to find!
- talk about, recommend & link to this blog and articles
- thanks to all who contribute!