Dernière mise-à-jour : 2020/01/30 03:28
A shell is a Command Line Interpreter (C.L.I). It is used to give instructions or commands to the operating system (OS).
The word shell is generic. There are many shells under Unix and Linux such as:
Shell | Name | Release Date | Inventer | Command | Comments |
---|---|---|---|---|---|
tsh | Thompson Shell | 1971 | Ken Thompson | sh | The first shell |
sh | Bourne Shell | 1977 | Stephen Bourne | sh | The shell common to all Unix and Linux OSs: /bin/sh |
csh | C-Shell | 1978 | Bill Joy | csh | The BSD shell: /bin/csh |
tcsh | Tenex C-Shell | 1979 | Ken Greer | tcsh | A fork of the csh shell: /bin/tcsh |
ksh | Korn Shell | 1980 | David Korn | ksh | Open Source since 2005: /bin/ksh |
bash | Bourne Again Shell | 1987 | Brian Fox | bash | The default shell for Linux, MacOS X, Solaris 11: /bin/bash |
zsh | Z Shell | 1990 | Paul Falstad | zsh | Zsh is an extended Bourne shell with a large number of improvements, including some features of bash, ksh, and tcsh: /usr/bin/zsh |
When using Debian 8 /bin/sh is a soft link to /bin/dash :
trainee@debian8:~$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Nov 8 2014 /bin/sh -> dash
When using Ubuntu 16.04 /bin/sh is a soft link to /bin/dash :
trainee@ubuntu1604:~$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 mai 3 2016 /bin/sh -> dash
When using RHEL/CentOS 7 /bin/sh is a soft link to /bin/bash :
[trainee@centos7 ~]$ ls -l /bin/sh lrwxrwxrwx. 1 root root 4 30 sept. 06:01 /bin/sh -> bash
When using SLES 12 /bin/sh is a soft link to /bin/bash :
trainee@SLES12SP1:~> ls -l /bin/sh lrwxrwxrwx 1 root root 4 1 mai 2016 /bin/sh -> bash
This unit covers the /bin/bash shell. The /bin/bash shell allows you to:
A command always starts with a keyword. This keyword is interpreted by the shell, in the order shown, as one of the following:
The /bin/bash shell comes with a set of built-in or internal commands. External commands are executable binaries or scripts generally found in one of the following directories:
To check if a command is internal to the shell or external, use the type command:
trainee@debian8:~$ type cd cd is a shell builtin
trainee@ubuntu1604:~$ type cd cd is a shell builtin
[trainee@centos7 ~]$ type cd cd is a shell builtin
trainee@SLES12SP1:~> type cd cd is a shell builtin
External commands are either binaries or scripts that can be found in /bin, /sbin, /usr/bin or /usr/sbin :
trainee@debian8:~$ type passwd passwd is /usr/bin/passwd
trainee@ubuntu1604:~$ type passwd passwd is /usr/bin/passwd
[trainee@centos7 ~]$ type passwd passwd is /usr/bin/passwd
trainee@SLES12SP1:~> type passwd passwd is /usr/bin/passwd
Aliases are strings that are aliased to a command, a command and some options or even several commands. Aliases are specific to the shell in which they are created and unless specified in one of the start-up files, they disappear when the shell is closed:
trainee@debian8:~$ type ls ls is aliased to `ls --color=auto
trainee@ubuntu1604:~$ type ls ls is aliased to `ls --color=auto'
[trainee@centos7 ~]$ type ls ls is aliased to `ls --color=auto'
trainee@SLES12SP1:~> type ls ls is aliased to `_ls'
Important: Note that the ls alias is an alias to the ls command itself.
An alias is defined using the alias command:
trainee@debian8:~$ alias dir='ls -l' trainee@debian8:~$ dir total 36 -rw-r--r-- 1 trainee trainee 0 Aug 19 17:08 aac -rw-r--r-- 1 trainee trainee 0 Aug 19 17:08 abc -rw-r--r-- 1 trainee trainee 0 Aug 19 17:08 bca drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Desktop drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Documents drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Downloads drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Music drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Pictures drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Public drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Templates drwxr-xr-x 2 trainee trainee 4096 May 1 2016 Videos -rw-r--r-- 1 trainee trainee 391 Aug 18 23:34 vitext -rw-r--r-- 1 trainee trainee 0 Aug 19 17:08 xyz
trainee@ubuntu1604:~$ alias dir='ls -l' trainee@ubuntu1604:~$ dir total 48 -rw-rw-r-- 1 trainee trainee 0 oct. 4 14:24 aac -rw-rw-r-- 1 trainee trainee 0 oct. 4 14:24 abc -rw-rw-r-- 1 trainee trainee 0 oct. 4 14:24 bca drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Desktop drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Documents drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Downloads -rw-r--r-- 1 trainee trainee 8980 mai 3 2016 examples.desktop drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Music drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Pictures drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Public drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Templates drwxr-xr-x 2 trainee trainee 4096 mai 3 2016 Videos -rw-rw-r-- 1 trainee trainee 442 sept. 30 11:35 vitext -rw-rw-r-- 1 trainee trainee 0 oct. 4 14:24 xyz
[trainee@centos7 ~]$ alias dir='ls -l' [trainee@centos7 ~]$ dir total 4 -rw-rw-r--. 1 trainee trainee 0 29 sept. 18:20 aac -rw-rw-r--. 1 trainee trainee 0 29 sept. 18:20 abc -rw-rw-r--. 1 trainee trainee 0 29 sept. 18:20 bca drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Desktop drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Documents drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Downloads drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Music drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Pictures drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Public drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Templates drwxr-xr-x. 2 trainee trainee 6 30 avril 11:54 Videos -rw-rw-r--. 1 trainee trainee 442 29 sept. 00:53 vitext -rw-rw-r--. 1 trainee trainee 0 29 sept. 18:20 xyz
trainee@SLES12SP1:~> alias dir='ls -l' trainee@SLES12SP1:~> dir total 4 -rw-r--r-- 1 trainee users 0 1 oct. 06:55 aac -rw-r--r-- 1 trainee users 0 1 oct. 06:55 abc -rw-r--r-- 1 trainee users 0 1 oct. 06:55 bca drwxr-xr-x 1 trainee users 0 1 mai 2016 bin drwxr-xr-x 1 trainee users 0 2 mai 2016 Desktop drwxr-xr-x 1 trainee users 0 2 mai 2016 Documents drwxr-xr-x 1 trainee users 0 2 mai 2016 Downloads drwxr-xr-x 1 trainee users 0 2 mai 2016 Music drwxr-xr-x 1 trainee users 0 2 mai 2016 Pictures drwxr-xr-x 1 trainee users 0 2 mai 2016 Public drwxr-xr-x 1 trainee users 20 1 mai 2016 public_html drwxr-xr-x 1 trainee users 0 2 mai 2016 Templates drwxr-xr-x 1 trainee users 0 2 mai 2016 Videos -rw-r--r-- 1 trainee users 391 30 sept. 10:27 vitext -rw-r--r-- 1 trainee users 0 1 oct. 06:55 xyz
Important: Note that dir exists as a command. By creating an alias of the same name, the alias will be executed in place of the command.
The list of currently defined aliases is obtained by using the alias command with no options:
trainee@debian8:~$ alias alias dir='ls -l' alias ls='ls --color=auto'
trainee@ubuntu1604:~$ alias alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' alias dir='ls -l' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l='ls -CF' alias la='ls -A' alias ll='ls -alF' alias ls='ls --color=auto'
[trainee@centos7 ~]$ alias alias dir='ls -l' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' alias ls='ls --color=auto' alias vi='vim' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
trainee@SLES12SP1:~> alias alias +='pushd .' alias -='popd' alias ..='cd ..' alias ...='cd ../..' alias aumix='padsp aumix' alias beep='echo -en "\007"' alias cd..='cd ..' alias dir='ls -l' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l='ls -alF' alias la='ls -la' alias ll='ls -l' alias ls='_ls' alias ls-l='ls -l' alias md='mkdir -p' alias o='less' alias rd='rmdir' alias rehash='hash -r' alias sox='padsp sox' alias timidity='timidity -Oe' alias unmount='echo "Error: Try the command: umount" 1>&2; false' alias you='if test "$EUID" = 0 ; then /sbin/yast2 online_update ; else su - -c "/sbin/yast2 online_update" ; fi'
Important: In the above list you can see, without distinction, the system wide aliases created by system start up scripts and the user created alias dir. The latter is only available for trainee and will disappear when the current session is terminated.
To force the shell to use the command and not the alias, you can precede the command with the \ character:
trainee@debian8:~$ \dir aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@ubuntu1604:~$ \dir aac bca Documents examples.desktop Pictures Templates vitext abc Desktop Downloads Music Public Videos xyz
[trainee@centos7 ~]$ \dir aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@SLES12SP1:~> \dir aac bca Desktop Downloads Pictures public_html Videos xyz abc bin Documents Music Public Templates vitext
To delete an alias, simply use the unalias command:
trainee@debian8:~$ unalias dir trainee@debian8:~$ dir aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@ubuntu1604:~$ unalias dir trainee@ubuntu1604:~$ dir aac bca Documents examples.desktop Pictures Templates vitext abc Desktop Downloads Music Public Videos xyz
[trainee@centos7 ~]$ unalias dir [trainee@centos7 ~]$ dir aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@SLES12SP1:~> unalias dir trainee@SLES12SP1:~> dir aac bca Desktop Downloads Pictures public_html Videos xyz abc bin Documents Music Public Templates vitext
Each user's shell is defined by root in the /etc/passwd file:
trainee@debian8:~$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false trainee:x:1000:1000:trainee,,,:/home/trainee:/bin/bash sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin Debian-exim:x:105:110::/var/spool/exim4:/bin/false messagebus:x:106:111::/var/run/dbus:/bin/false statd:x:107:65534::/var/lib/nfs:/bin/false avahi-autoipd:x:108:113:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false avahi:x:109:115:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false colord:x:110:117:colord colour management daemon,,,:/var/lib/colord:/bin/false dnsmasq:x:111:65534:dnsmasq,,,:/var/lib/misc:/bin/false speech-dispatcher:x:112:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh pulse:x:113:119:PulseAudio daemon,,,:/var/run/pulse:/bin/false rtkit:x:114:121:RealtimeKit,,,:/proc:/bin/false saned:x:115:122::/var/lib/saned:/bin/false usbmux:x:116:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false lightdm:x:117:124:Light Display Manager:/var/lib/lightdm:/bin/false
trainee@ubuntu1604:~$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false syslog:x:104:108::/home/syslog:/bin/false _apt:x:105:65534::/nonexistent:/bin/false messagebus:x:106:110::/var/run/dbus:/bin/false uuidd:x:107:111::/run/uuidd:/bin/false lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin/false whoopsie:x:109:116::/nonexistent:/bin/false avahi-autoipd:x:110:119:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false avahi:x:111:120:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/bin/false colord:x:113:123:colord colour management daemon,,,:/var/lib/colord:/bin/false speech-dispatcher:x:114:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false hplip:x:115:7:HPLIP system user,,,:/var/run/hplip:/bin/false kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false pulse:x:117:124:PulseAudio daemon,,,:/var/run/pulse:/bin/false rtkit:x:118:126:RealtimeKit,,,:/proc:/bin/false saned:x:119:127::/var/lib/saned:/bin/false usbmux:x:120:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false trainee:x:1000:1000:trainee,,,:/home/trainee:/bin/bash sshd:x:121:65534::/var/run/sshd:/usr/sbin/nologin
[trainee@centos7 ~]$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:997:995:User for polkitd:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin colord:x:996:993:User for colord:/var/lib/colord:/sbin/nologin libstoragemgmt:x:995:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin setroubleshoot:x:994:991::/var/lib/setroubleshoot:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin chrony:x:993:990::/var/lib/chrony:/sbin/nologin unbound:x:992:989:Unbound DNS resolver:/etc/unbound:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin geoclue:x:991:988:User for geoclue:/var/lib/geoclue:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin sssd:x:990:987:User for sssd:/:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin gnome-initial-setup:x:989:984::/run/gnome-initial-setup/:/sbin/nologin avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin trainee:x:1000:1000:trainee:/home/trainee:/bin/bash vboxadd:x:988:1::/var/run/vboxadd:/bin/false named:x:25:25:Named:/var/named:/sbin/nologin
trainee@SLES12SP1:~> cat /etc/passwd at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash bin:x:1:1:bin:/bin:/bin/bash daemon:x:2:2:Daemon:/sbin:/bin/bash ftp:x:40:49:FTP account:/srv/ftp:/bin/bash ftpsecure:x:488:65534:Secure FTP User:/var/lib/empty:/bin/false games:x:12:100:Games account:/var/games:/bin/bash gdm:x:486:485:Gnome Display Manager daemon:/var/lib/gdm:/bin/false lp:x:4:7:Printing daemon:/var/spool/lpd:/bin/bash mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false man:x:13:62:Manual pages viewer:/var/cache/man:/bin/bash messagebus:x:499:499:User for D-Bus:/var/run/dbus:/bin/false news:x:9:13:News system:/etc/news:/bin/bash nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash nscd:x:496:495:User for nscd:/run/nscd:/sbin/nologin ntp:x:74:492:NTP daemon:/var/lib/ntp:/bin/false openslp:x:494:2:openslp daemon:/var/lib/empty:/sbin/nologin polkitd:x:497:496:User for polkitd:/var/lib/polkit:/sbin/nologin postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/bin/false pulse:x:490:489:PulseAudio daemon:/var/lib/pulseaudio:/sbin/nologin root:x:0:0:root:/root:/bin/bash rpc:x:495:65534:user for rpcbind:/var/lib/empty:/sbin/nologin rtkit:x:491:490:RealtimeKit:/proc:/bin/false scard:x:487:487:Smart Card Reader:/var/run/pcscd:/usr/sbin/nologin sshd:x:498:498:SSH daemon:/var/lib/sshd:/bin/false statd:x:489:65534:NFS statd daemon:/var/lib/nfs:/sbin/nologin usbmux:x:493:65534:usbmuxd daemon:/var/lib/usbmuxd:/sbin/nologin uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash vnc:x:492:491:user for VNC:/var/lib/empty:/sbin/nologin wwwrun:x:30:8:WWW daemon apache:/var/lib/wwwrun:/bin/false trainee:x:1000:100:trainee:/home/trainee:/bin/bas
However, each user can change his shell using the chsh command. The shells available to users are listed in the /etc/shells file:
trainee@debian8:~$ cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash /usr/bin/screen
trainee@ubuntu1604:~$ cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash /usr/bin/screen
[trainee@centos7 ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh
trainee@SLES12SP1:~> cat /etc/shells /bin/ash /bin/bash /bin/csh /bin/dash /bin/false /bin/ksh /bin/ksh93 /bin/mksh /bin/pdksh /bin/sh /bin/tcsh /bin/true /bin/zsh /usr/bin/csh /usr/bin/dash /usr/bin/ksh /usr/bin/ksh93 /usr/bin/mksh /usr/bin/passwd /usr/bin/pdksh /usr/bin/bash /usr/bin/tcsh /usr/bin/zsh
Now use the echo command to view the contents of the system variable SHELL for your current session:
trainee@debian8:~$ echo $SHELL /bin/bash
trainee@ubuntu1604:~$ echo $SHELL /bin/bash
[trainee@centos7 ~]$ echo $SHELL /bin/bash
trainee@SLES12SP1:~> echo $SHELL /bin/bash
Important : Note that when using RHEL/CentOS 7 the output shows that trainee's shell is /bin/bash and not /usr/bin/bash. This is because /bin is a soft link to /usr/bin.
Now change your shell to /bin/sh using the chsh command:
trainee@debian8:~$ chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/bash]: /bin/sh
trainee@ubuntu1604:~$ chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/bash]: /bin/sh
[trainee@centos7 ~]$ chsh Changing shell for trainee. New shell [/bin/bash]: /bin/sh Password: trainee Shell changed.
trainee@SLES12SP1:~> chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/bash]: /bin/sh
Important: Note that the password will not be printed to standard output.
Now check your current shell:
trainee@debian8:~$ echo $SHELL /bin/bash
trainee@ubuntu1604:~$ echo $SHELL /bin/bash
[trainee@centos7 ~]$ echo $SHELL /bin/bash
trainee@SLES12SP1:~> echo $SHELL /bin/bash
At first glance nothing has happened. However if you view your entry in the /etc/passwd file you will notice that your login shell has changed:
trainee@debian8:~$ cat /etc/passwd | grep trainee trainee:x:1000:1000:trainee,,,:/home/trainee:/bin/sh
trainee@ubuntu1604:~$ cat /etc/passwd | grep trainee trainee:x:1000:1000:trainee,,,:/home/trainee:/bin/sh
[trainee@centos7 ~]$ cat /etc/passwd | grep trainee trainee:x:1000:1000:trainee:/home/trainee:/bin/sh
trainee@SLES12SP1:~> cat /etc/passwd | grep trainee trainee:x:1000:100:trainee:/home/trainee:/bin/sh
Important : The /bin/sh shell will be your active shell the next time you login.
Now change your shell back to /bin/bash using the chsh command:
trainee@debian8:~$ chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/sh]: /bin/bash
trainee@ubuntu1604:~$ chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/sh]: /bin/bash
[trainee@centos7 ~]$ chsh Changing shell for trainee. New shell [/bin/sh]: /bin/bash Password: trainee Shell changed.
trainee@SLES12SP1:~> chsh Password: trainee Changing the login shell for trainee Enter the new value, or press ENTER for the default Login Shell [/bin/sh]: /bin/bash
Important: Note that the password will not be printed to standard output.
As you have already noticed, the prompt under Linux is different for a normal user and root:
/bin/bash keeps track of commands that have been previously executed. To access the command history, use the following command:
trainee@debian8:~$ history | more 1 su - 2 su - 3 exit 4 su - 5 exit 6 ls -l /var 7 su - 8 su - 9 vi vitext 10 view vitext 11 clear 12 stty -a 13 date 14 who 15 df 16 df -h 17 free 18 free -h 19 whoami 20 su - 21 clear 22 su - 23 exit --More--
trainee@ubuntu1604:~$ history | more 1 sudo su - 2 vi vitext 3 view vitext 4 vi vitext 5 vi .exrc 6 vi vitext 7 clear 8 stty -a 9 date 10 locale 11 LANG=en_GB.UTF-8 12 export LANG 13 locale 14 date 15 LC_ALL=en_GB.UTF-8 16 export LC_ALL 17 locale 18 date 19 who 20 df 21 df -h 22 free 23 free -h --More--
[trainee@centos7 ~]$ history | more 1 su - 2 df -h 3 su - 4 exit 5 su - 6 su - 7 vi vitext 8 view vitext 9 vi vitext 10 locale 11 LANG=en_GB.UTF-8 12 export LANG 13 locale 14 vi vitext 15 vi .exrc 16 vi vitext 17 clear 18 stty -a 19 date 20 locale 21 who 22 df 23 df -h --More--
trainee@SLES12SP1:~> history | more 1 su - 2 su - 3 clear 4 cd / 5 ls -l 6 ls -l /var/run 7 cd /mnt 8 ls 9 cd 10 mount 11 mount --help 12 cat /etc/fstab 13 umount --help 14 dumpe2fs /dev/sda1 | grep -i superbloc 15 ls -ld /dev/console /dev/initctl /dev/loop0 /etc /etc/passwd 16 ls -ld /dev/console /dev/initctl /etc /etc/passwd 17 ls -ldi /dev/console /dev/initctl /etc /etc/passwd 18 cd /tmp; mkdir inode; cd inode; touch fichier1; ls -ali 19 ln fichier1 fichier2 20 ls -ali 21 ln -s fichier1 fichier3 22 ls -ali 23 su - --More--
Important: The history is specific to each user.
The history command uses emacs style control characters. As a result you can navigate through the list as follows:
Control Character | Action |
---|---|
[CTRL]-[P] (= Up Arrow) | Navigates backwards through the list |
[CTRL]-[N] (= Down Arrow) | Navigates forwards through the list |
To move around in the history:
Control Character | Action |
---|---|
[CTRL]-[A] | Move to the beginning of the line |
[CTRL]-[E] | Move to the end of the line |
[CTRL]-[B] | Move one character to the left |
[CTRL]-[F] | Move one character to the right |
[CTRL]-[D] | Delete the character under the cursor |
Pour rechercher dans l'historique il convient d'utiliser les touches :
Control Character | Action |
---|---|
[CTRL]-[R] string | Search backwards for string in the history. Using [CTRL]-[R] again will search for the previous occurence of string |
[CTRL]-[S] string | Search forwards for string in the history. Using [CTRL]-[S] again will search for the next occurence of string |
[CTRL]-[G] | Quit the search mode |
It is also possible to recall the last command executed by using the !! characters:
trainee@debian8:~$ ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext trainee@debian8:~$ !! ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@ubuntu1604:~$ ls aac bca Documents examples.desktop Pictures Templates vitext abc Desktop Downloads Music Public Videos xyz trainee@ubuntu1604:~$ !! ls aac bca Documents examples.desktop Pictures Templates vitext abc Desktop Downloads Music Public Videos xyz
[trainee@centos7 ~]$ ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext [trainee@centos7 ~]$ !! ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@SLES12SP1:~> ls aac bca Desktop Downloads Pictures public_html Videos xyz abc bin Documents Music Public Templates vitext trainee@SLES12SP1:~> !! ls aac bca Desktop Downloads Pictures public_html Videos xyz abc bin Documents Music Public Templates vitext
Alternatively, to execute a command in the list, you can use the list number preceded by the ! character:
trainee@debian8:~$ !52 ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@ubuntu1604:~$ !107 ls aac bca Documents examples.desktop Pictures Templates vitext abc Desktop Downloads Music Public Videos xyz
[trainee@centos7 ~]$ !123 ls aac bca Documents Music Public Videos xyz abc Desktop Downloads Pictures Templates vitext
trainee@SLES12SP1:~> !131 ls aac bca Desktop Downloads Pictures public_html Videos xyz abc bin Documents Music Public Templates vitext
The environmental variables associated with the history are set system-wide in the /etc/profile file. When using Debian or Ubuntu however, the values are set in the ~/.bashrc file where ~/ indicates the home directory of the user concerned:
trainee@debian8:~$ cat .bashrc | grep HISTSIZE # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000
trainee@ubuntu1604:~$ cat .bashrc | grep HISTSIZE # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000
[trainee@centos7 ~]$ cat /etc/profile | grep HISTSIZE HISTSIZE=1000 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
trainee@SLES12SP1:~> cat /etc/profile | grep HISTSIZE HISTSIZE=1000 export HISTSIZE
As you can see, in the previous case the HISTSIZE value is set to 1000. This means that the last 1,000 commands are held in the history.
The history command stores data in the ~/.bash_history file for each user. The commands for the current bash session are stored in the file when the session is closed:
trainee@debian8:~$ nl .bash_history | more 1 su - 2 su - 3 exit 4 su - 5 exit 6 ls -l /var 7 su - 8 su - 9 vi vitext 10 view vitext 11 clear 12 stty -a 13 date 14 who 15 df 16 df -h 17 free 18 free -h 19 whoami 20 su - 21 clear 22 su - 23 exit --More--
trainee@ubuntu1604:~$ nl .bash_history | more 1 sudo su - 2 vi vitext 3 view vitext 4 vi vitext 5 vi .exrc 6 vi vitext 7 clear 8 stty -a 9 date 10 locale 11 LANG=en_GB.UTF-8 12 export LANG 13 locale 14 date 15 LC_ALL=en_GB.UTF-8 16 export LC_ALL 17 locale 18 date 19 who 20 df 21 df -h 22 free 23 free -h --More--
[trainee@centos7 ~]$ nl .bash_history | more 1 su - 2 df -h 3 su - 4 exit 5 su - 6 su - 7 vi vitext 8 view vitext 9 vi vitext 10 locale 11 LANG=en_GB.UTF-8 12 export LANG 13 locale 14 vi vitext 15 vi .exrc 16 vi vitext 17 clear 18 stty -a 19 date 20 locale 21 who 22 df 23 df -h --More--
trainee@SLES12SP1:~> nl .bash_history | more 1 su - 2 su - 3 clear 4 cd / 5 ls -l 6 ls -l /var/run 7 cd /mnt 8 ls 9 cd - 10 mount 11 mount --help 12 cat /etc/fstab 13 umount --help 14 dumpe2fs /dev/sda1 | grep -i superbloc 15 ls -ld /dev/console /dev/initctl /dev/loop0 /etc /etc/passwd 16 ls -ld /dev/console /dev/initctl /etc /etc/passwd 17 ls -ldi /dev/console /dev/initctl /etc /etc/passwd 18 cd /tmp; mkdir inode; cd inode; touch fichier1; ls -ali 19 ln fichier1 fichier2 20 ls -ali 21 ln -s fichier1 fichier3 22 ls -ali 23 su - --More--
Important : Note the use of the nl command to number the lines in the output of the contents of .bash_history file.
/bin/bash can auto-generate the end of a file name. Consider the following example:
$ ls .b [Tab][Tab][Tab]
By hitting the Tab key three times, the system shows you the files that match:
trainee@debian8:~$ ls .bash .bash_history .bash_logout .bashrc
trainee@ubuntu1604:~$ ls .bash .bash_history .bash_logout .bashrc
[trainee@centos7 ~]$ ls .bash .bash_history .bash_logout .bash_profile .bashrc
trainee@SLES12SP1:~> ls .bash .bash_history .bashrc
Important : Note that when using Debian or Ubuntu, the .bash_profile file does not exist. In the case of both of these distributions, the file is replaced by the .profile file.
This same technique can also be used to auto-generate command names. Consider the following example:
$ mo [Tab][Tab]
By hitting the Tab twice the system lists all known commands available to the user and starting with mo:
trainee@debian8:~$ mo moc moggsplit more mount mountpoint mousepad
trainee@ubuntu1604:~$ mo moc mogrify-im6 mount mount.ntfs modinfo montage mountall mount.ntfs-3g modprobe montage-im6 mount.fuse mountpoint mogrify more mount.lowntfs-3g mousetweaks
[trainee@centos7 ~]$ mo mobj_dump modutil mount.cifs mount.nfs4 mousetweaks modifyrepo mokutil mount.fuse mountpoint modinfo more mount.glusterfs mountstats modprobe mount mount.nfs mount.vboxsf
trainee@SLES12SP1:~> mo modeprint modsign-verify mount mouse-test modetest more mountpoint
It is often necessary and desirable to be able to work with several files at one time as opposed to repeating the operation on each file individually. For this reason, bash accepts the use of Metacharacters:
Metacharacter | Description |
---|---|
* | Matches one or more characters |
? | Matches a single character |
[abc] | Matches any one of the characters between square brackets |
[!abc] | Matches any character except those between square brackets |
[m-t] | Matches any character from m through to t |
[!m-t] | Matches any character other than m through to t |
?(expression1|expression2| …) | Matches 0 or 1 occurence of expression1 OR 0 or 1 occurence of expression2 OR … |
*(expression1|expression2| …) | Matches 0 to x occurences of expression1 OR 0 to x occurences of expression2 OR … |
+(expression1|expression2| …) | Matches 1 to x occurences of expression1 OR 1 to x occurences of expression2 OR … |
@(expression1|expression2| …) | Matches 1 occurrence of expression1 OR 1 occurence of expression2 OR … |
!(expression1|expression2| …) | Matches 0 occurrences of expression1 OR 0 occurrences of expression2 OR … |
To illustrate the use of Metacharacters, you need to create a directory in your home directory and the create some files within it:
trainee@debian8:~$ mkdir training trainee@debian8:~$ cd training trainee@debian8:~/training$ touch f1 f2 f3 f4 f5
trainee@ubuntu1604:~$ mkdir training trainee@ubuntu1604:~$ cd training trainee@ubuntu1604:~/training$ touch f1 f2 f3 f4 f5
[trainee@centos7 ~]$ mkdir training [trainee@centos7 ~]$ cd training [trainee@centos7 training]$ touch f1 f2 f3 f4 f5
trainee@SLES12SP1:~> mkdir training trainee@SLES12SP1:~> cd training trainee@SLES12SP1:~/training> touch f1 f2 f3 f4 f5
Now use the Metacharacter *:
trainee@debian8:~/training$ echo f* f1 f2 f3 f4 f5
trainee@ubuntu1604:~/training$ echo f* f1 f2 f3 f4 f5
[trainee@centos7 training]$ echo f* f1 f2 f3 f4 f5
trainee@SLES12SP1:~/training> echo f* f1 f2 f3 f4 f5
Important: Note that the * is used as a wild card which replaces 0 or more characters.
Create two more files:
trainee@debian8:~/training$ touch f52 f62
trainee@ubuntu1604:~/training$ touch f52 f62
[trainee@centos7 training]$ touch f52 f62
trainee@SLES12SP1:~/training> touch f52 f62
Now use the Metacharacter ?:
trainee@debian8:~/training$ echo f?2 f52 f62
trainee@ubuntu1604:~/training$ echo f?2 f52 f62
[trainee@centos7 training]$ echo f?2 f52 f62
trainee@SLES12SP1:~/training> echo f?2 f52 f62
Important: Note that the ? is used as a wild card which replaces a single character.
The [] Metacharacter can take several forms:
Metacharacter | Description |
---|---|
[xyz] | Represents either x or y or z |
[m-t] | |
[!xyz] | Represents any character other than x or y or z |
[!m-t] | Represents any character outside of the range m to t |
To demonstrate the use of the metacharacter [], create a file called a100:
trainee@debian8:~/training$ touch a100
trainee@ubuntu1604:~/training$ touch a100
[trainee@centos7 training]$ touch a100
trainee@SLES12SP1:~/training> touch a100
The use of this Metacharacter can be demonstrated with the following examples:
trainee@debian8:~/training$ echo [a-f]* a100 f1 f2 f3 f4 f5 f52 f62 trainee@debian8:~/training$ echo [af]* a100 f1 f2 f3 f4 f5 f52 f62
trainee@ubuntu1604:~/training$ echo [a-f]* a100 f1 f2 f3 f4 f5 f52 f62 trainee@ubuntu1604:~/training$ echo [af]* a100 f1 f2 f3 f4 f5 f52 f62
[trainee@centos7 training]$ echo [a-f]* a100 f1 f2 f3 f4 f5 f52 f62 [trainee@centos7 training]$ echo [af]* a100 f1 f2 f3 f4 f5 f52 f62
trainee@SLES12SP1:~/training> echo [a-f]* a100 f1 f2 f3 f4 f5 f52 f62 trainee@SLES12SP1:~/training> echo [af]* a100 f1 f2 f3 f4 f5 f52 f62
Important: Note that all the files starting with either a, b, c, d, e or f are displayed.
trainee@debian8:~/training$ echo [!a]* f1 f2 f3 f4 f5 f52 f62
trainee@ubuntu1604:~/training$ echo [!a]* f1 f2 f3 f4 f5 f52 f62
[trainee@centos7 training]$ echo [!a]* f1 f2 f3 f4 f5 f52 f62
trainee@SLES12SP1:~/training> echo [!a]* f1 f2 f3 f4 f5 f52 f62
Important: Note that all the files in the directory are displayed except the file starting with a .
trainee@debian8:~/training$ echo [a-b]* a100
trainee@ubuntu1604:~/training$ echo [a-b]* a100
[trainee@centos7 training]$ echo [a-b]* a100
trainee@SLES12SP1:~/training> echo [a-b]* a100
Important: Note that only the file starting with a is displayed since no file starting with b is present.
trainee@debian8:~/training$ echo [a-f] [a-f]
trainee@ubuntu1604:~/training$ echo [a-f] [a-f]
[trainee@centos7 training]$ echo [a-f] [a-f]
trainee@SLES12SP1:~/training> echo [a-f] [a-f]
Important: Note that in the above example, since no file called a, b, c, d, e or f exists in the directory, the echo command simply returns the filter used.
In order to use ?(expression), *(expression), +(expression), @(expression) and !(expression), you need to activate the extglob option:
trainee@debian8:~/training$ shopt -s extglob
trainee@ubuntu1604:~/training$ shopt -s extglob
[trainee@centos7 training]$ shopt -s extglob
trainee@SLES12SP1:~/training> shopt -s extglob
The shopt command is used to activate and deactivate the shopt option of the shell.
The list of all the options can be displayed by simply using the shopt command:
trainee@debian8:~/training$ shopt autocd off cdable_vars off cdspell off checkhash off checkjobs off checkwinsize on cmdhist on compat31 off compat32 off compat40 off compat41 off compat42 off complete_fullquote on direxpand off dirspell off dotglob off execfail off expand_aliases on extdebug off extglob on extquote on failglob off force_fignore on globstar off globasciiranges off gnu_errfmt off histappend on histreedit off histverify off hostcomplete off huponexit off interactive_comments on lastpipe off lithist off login_shell on mailwarn off no_empty_cmd_completion off nocaseglob off nocasematch off nullglob off progcomp on promptvars on restricted_shell off shift_verbose off sourcepath on xpg_echo off
trainee@ubuntu1604:~/training$ shopt autocd off cdable_vars off cdspell off checkhash off checkjobs off checkwinsize on cmdhist on compat31 off compat32 off compat40 off compat41 off compat42 off complete_fullquote on direxpand off dirspell off dotglob off execfail off expand_aliases on extdebug off extglob on extquote on failglob off force_fignore on globstar off globasciiranges off gnu_errfmt off histappend on histreedit off histverify off hostcomplete off huponexit off interactive_comments on lastpipe off lithist off login_shell on mailwarn off no_empty_cmd_completion off nocaseglob off nocasematch off nullglob off progcomp on promptvars on restricted_shell off shift_verbose off sourcepath on xpg_echo off
[trainee@centos7 training]$ shopt autocd off cdable_vars off cdspell off checkhash off checkjobs off checkwinsize on cmdhist on compat31 off compat32 off compat40 off compat41 off direxpand off dirspell off dotglob off execfail off expand_aliases on extdebug off extglob on extquote on failglob off force_fignore on globstar off gnu_errfmt off histappend on histreedit off histverify off hostcomplete off huponexit off interactive_comments on lastpipe off lithist off login_shell on mailwarn off no_empty_cmd_completion off nocaseglob off nocasematch off nullglob off progcomp on promptvars on restricted_shell off shift_verbose off sourcepath on xpg_echo of
trainee@SLES12SP1:~/training> shopt autocd off cdable_vars off cdspell off checkhash off checkjobs off checkwinsize on cmdhist on compat31 off compat32 off compat40 off compat41 off direxpand off dirspell off dotglob off execfail off expand_aliases on extdebug off extglob on extquote on failglob off force_fignore on globstar off gnu_errfmt off histappend on histreedit off histverify off hostcomplete off huponexit off interactive_comments on lastpipe off lithist off login_shell on mailwarn off no_empty_cmd_completion off nocaseglob off nocasematch off nullglob off progcomp on promptvars on restricted_shell off shift_verbose off sourcepath on xpg_echo off
Create the following files:
trainee@debian8:~/training$ touch f f.txt f123.txt f123123.txt f123123123.txt
trainee@ubuntu1604:~/training$ touch f f.txt f123.txt f123123.txt f123123123.txt
[trainee@centos7 training]$ touch f f.txt f123.txt f123123.txt f123123123.txt
trainee@SLES12SP1:~/training> touch f f.txt f123.txt f123123.txt f123123123.txt
Execute the following command:
trainee@debian8:~/training$ ls f?(123).txt f123.txt f.txt
trainee@ubuntu1604:~/training$ ls f?(123).txt f123.txt f.txt
[trainee@centos7 training]$ ls f?(123).txt f123.txt f.txt
trainee@SLES12SP1:~/training> ls f?(123).txt f123.txt f.txt
Important: Note that the command displays file names that match 0 or 1 occurrences of the string 123.
Execute the following command:
trainee@debian8:~/training$ ls f*(123).txt f123123123.txt f123123.txt f123.txt f.txt
trainee@ubuntu1604:~/training$ ls f*(123).txt f123123123.txt f123123.txt f123.txt f.txt
[trainee@centos7 training]$ ls f*(123).txt f123123123.txt f123123.txt f123.txt f.txt
trainee@SLES12SP1:~/training> ls f*(123).txt f123123123.txt f123123.txt f123.txt f.txt
Important: Note that the command displays file names that match 0 to x occurrences of the string 123.
Execute the following command:
trainee@debian8:~/training$ ls f+(123).txt f123123123.txt f123123.txt f123.txt
trainee@ubuntu1604:~/training$ ls f+(123).txt f123123123.txt f123123.txt f123.txt
[trainee@centos7 training]$ ls f+(123).txt f123123123.txt f123123.txt f123.txt
trainee@SLES12SP1:~/training> ls f+(123).txt f123123123.txt f123123.txt f123.txt
Important: Note that the command displays file names that match 1 to x occurrences of the string 123..
Execute the following command:
trainee@debian8:~/training$ ls f@(123).txt f123.txt
trainee@ubuntu1604:~/training$ ls f@(123).txt f123.txt
[trainee@centos7 training]$ ls f@(123).txt f123.txt
trainee@SLES12SP1:~/training> ls f@(123).txt f123.txt
Important: Note that the command displays file names that match 1 occurrence of the string 123.
Execute the following command:
trainee@debian8:~/training$ ls f!(123).txt f123123123.txt f123123.txt f.txt
trainee@ubuntu1604:~/training$ ls f!(123).txt f123123123.txt f123123.txt f.txt
[trainee@centos7 training]$ ls f!(123).txt f123123123.txt f123123.txt f.txt
trainee@SLES12SP1:~/training> ls f!(123).txt f123123123.txt f123123.txt f.txt
Important: Note that the command displays file names that match 0 or x occurrences of the string 123, where x>1.
To cancel the wild card effect of a special character, the character needs to be escaped or “protected”:
Character | Description |
---|---|
\ | Escapes the character which immediately follows |
' ' | Protects any character between the two ' |
“ ” | Protects any character between the two “ except the following: $, \ and ' |
For example:
trainee@debian8:~/training$ echo * est un caractère spécial a100 f f1 f123123123.txt f123123.txt f123.txt f2 f3 f4 f5 f52 f62 f.txt est un caractère spécial trainee@debian8:~/training$ echo \* est un caractère spécial * est un caractère spécial trainee@debian8:~/training$ echo "* est un caractère spécial" * est un caractère spécial trainee@debian8:~/training$ echo '* est un caractère spécial' * est un caractère spécial
trainee@ubuntu1604:~/training$ echo * est un caractère spécial a100 f f1 f123123123.txt f123123.txt f123.txt f2 f3 f4 f5 f52 f62 f.txt est un caractère spécial trainee@ubuntu1604:~/training$ echo \* est un caractère spécial * est un caractère spécial trainee@ubuntu1604:~/training$ echo "* est un caractère spécial" * est un caractère spécial trainee@ubuntu1604:~/training$ echo '* est un caractère spécial' * est un caractère spécial
[trainee@centos7 training]$ echo * est un caractère spécial a100 f f1 f123123123.txt f123123.txt f123.txt f2 f3 f4 f5 f52 f62 f.txt est un caractère spécial [trainee@centos7 training]$ echo \* est un caractère spécial * est un caractère spécial [trainee@centos7 training]$ echo "* est un caractère spécial" * est un caractère spécial [trainee@centos7 training]$ echo '* est un caractère spécial' * est un caractère spécial
trainee@SLES12SP1:~/training> echo * est un caractère spécial a100 f f1 f123123123.txt f123123.txt f123.txt f2 f3 f4 f5 f52 f62 f.txt est un caractère spécial trainee@SLES12SP1:~/training> echo \* est un caractère spécial * est un caractère spécial trainee@SLES12SP1:~/training> echo "* est un caractère spécial" * est un caractère spécial trainee@SLES12SP1:~/training> echo '* est un caractère spécial' * est un caractère spécial
Each command returns an exit status when it is executed. This exit status is stored in a special variable: $?.
For example:
trainee@debian8:~/training$ cd .. trainee@debian8:~$ mkdir codes trainee@debian8:~$ echo $? 0 trainee@debian8:~$ touch codes/exit.txt trainee@debian8:~$ rmdir codes rmdir: failed to remove ‘codes’: Directory not empty trainee@debian8:~$ echo $? 1
trainee@ubuntu1604:~/training$ cd .. trainee@ubuntu1604:~$ mkdir codes trainee@ubuntu1604:~$ echo $? 0 trainee@ubuntu1604:~$ touch codes/exit.txt trainee@ubuntu1604:~$ rmdir codes rmdir: failed to remove 'codes': Directory not empty trainee@ubuntu1604:~$ echo $? 1
[trainee@centos7 training]$ cd .. [trainee@centos7 ~]$ mkdir codes [trainee@centos7 ~]$ echo $? 0 [trainee@centos7 ~]$ touch codes/exit.txt [trainee@centos7 ~]$ rmdir codes rmdir: failed to remove ‘codes’: Directory not empty [trainee@centos7 ~]$ echo $? 1
trainee@SLES12SP1:~/training> cd .. trainee@SLES12SP1:~> mkdir codes trainee@SLES12SP1:~> echo $? 0 trainee@SLES12SP1:~> touch codes/exit.txt trainee@SLES12SP1:~> rmdir codes rmdir: failed to remove ‘codes’: Directory not empty trainee@SLES12SP1:~> echo $? 1
As you can see when the exit status is 0, the command executes correctly. If the exit status is anything else, the command executes with errors.
Your dialogue with the system uses three file descriptors:
The standard output can be redirected using the > character:
trainee@debian8:~$ pwd /home/trainee trainee@debian8:~$ cd training trainee@debian8:~/training$ free > file trainee@debian8:~/training$ cat file total used free shared buffers cached Mem: 506268 429624 76644 4804 59540 130524 -/+ buffers/cache: 239560 266708 Swap: 2046972 0 2046972
trainee@ubuntu1604:~$ pwd /home/trainee trainee@ubuntu1604:~$ cd training trainee@ubuntu1604:~/training$ free > file trainee@ubuntu1604:~/training$ cat file total used free shared buff/cache available Mem: 500144 160208 6548 5168 333388 307548 Swap: 1997820 0 1997820
[trainee@centos7 ~]$ pwd /home/trainee [trainee@centos7 ~]$ cd training [trainee@centos7 training]$ free > file [trainee@centos7 training]$ cat file total used free shared buff/cache available Mem: 500780 192692 38916 4824 269172 260472 Swap: 2096124 0 2096124
trainee@SLES12SP1:~> pwd /home/trainee trainee@SLES12SP1:~> cd training trainee@SLES12SP1:~/training> free > file trainee@SLES12SP1:~/training> cat file total used free shared buffers cached Mem: 394524 386024 8500 5716 452 300420 -/+ buffers/cache: 85152 309372 Swap: 2103292 4 2103288
Important: If the file does not exist, it is automatically created.
Repeating a single redirection will replace the file:
trainee@debian8:~/training$ date > file trainee@debian8:~/training$ cat file Mon 28 Nov 14:48:03 GMT 2016
trainee@ubuntu1604:~/training$ date > file trainee@ubuntu1604:~/training$ cat file Mon 28 Nov 15:51:07 CET 2016
[trainee@centos7 training]$ date > file [trainee@centos7 training]$ cat file Mon 28 Nov 15:48:09 CET 2016
trainee@SLES12SP1:~/training> date > file trainee@SLES12SP1:~/training> cat file Mon 28 Nov 15:48:29 CET 2016
To add additional data to the file, you need to use a double redirection:
trainee@debian8:~/training$ free >> file trainee@debian8:~/training$ cat file Mon 28 Nov 14:48:03 GMT 2016 total used free shared buffers cached Mem: 506268 431668 74600 4804 60264 130912 -/+ buffers/cache: 240492 265776 Swap: 2046972 0 20469722
trainee@ubuntu1604:~/training$ free >> file trainee@ubuntu1604:~/training$ cat file Mon 28 Nov 15:51:07 CET 2016 total used free shared buff/cache available Mem: 500144 160208 6436 5168 333500 307548 Swap: 1997820 0 1997820
[trainee@centos7 training]$ free >> file [trainee@centos7 training]$ cat file Mon 28 Nov 15:48:09 CET 2016 total used free shared buff/cache available Mem: 500780 192792 38516 4824 269472 260376 Swap: 2096124 0 2096124
trainee@SLES12SP1:~/training> free >> file trainee@SLES12SP1:~/training> cat file Mon 28 Nov 15:48:29 CET 2016 total used free shared buffers cached Mem: 394524 386876 7648 5716 452 300936 -/+ buffers/cache: 85488 309036 Swap: 2103292 4 2103288
Important : Note that standard output can only be redirected to a single destination.
File descriptors are numbered for ease of use :
For example:
trainee@debian8:~/training$ cd .. trainee@debian8:~$ rmdir training/ 2>errorlog trainee@debian8:~$ cat erreurlog rmdir: failed to remove ‘training/’: Directory not empty
trainee@ubuntu1604:~/training$ cd .. trainee@ubuntu1604:~$ rmdir training/ 2>errorlog trainee@ubuntu1604:~$ cat erreurlog rmdir: failed to remove 'training/': Directory not empty
[trainee@centos7 training]$ cd .. [trainee@centos7 ~]$ rmdir training/ 2>errorlog [trainee@centos7 ~]$ cat erreurlog rmdir: failed to remove ‘training/’: Directory not emptyy
trainee@SLES12SP1:~/training> cd .. trainee@SLES12SP1:~> rmdir training/ 2>errorlog trainee@SLES12SP1:~> cat erreurlog rmdir: failed to remove ‘training/’: Directory not empty
Important: As you can see the error generated is redirected to the errorlog file.
You can join file descriptors using the & character:
trainee@debian8:~$ free > file 2>&1
trainee@ubuntu1604:~$ free > file 2>&1
[trainee@centos7 ~]$ free > file 2>&1
trainee@SLES12SP1:~> free > file 2>&1
Any errors are sent to the same destination as the standard output, in the case, file.
It is also possible to have a reverse redirection:
trainee@debian8:~$ wc -w < errorlog 8
trainee@ubuntu1604:~$ wc -w < errorlog 8
[trainee@centos7 ~]$ wc -w < errorlog 8
trainee@SLES12SP1:~> wc -w < errorlog 8
In this case wc -w counts the number of words in the file.
Other redirections exist :
Redirection | Definition |
---|---|
&> | Join file descriptors 1 and 2. |
<< | Takes the text typed on the next lines as standard input until EOF is found at the beginning of a line. |
<> | Allows the use of the same file as STDIN and STDOUT. |
A pipe is used to present the standard output on the first command to the standard input of the second command:
trainee@debian8:~$ ls | wc -w 17
trainee@ubuntu1604:~$ ls | wc -w 17
[trainee@centos7 ~]$ ls | wc -w 17
trainee@SLES12SP1:~> ls | wc -w 18
Important - Several pipes can be used within the same command.
Standard output can generally only be redirected to a single destination. To redirect to two destinations at once, you need to use the tee command:
trainee@debian8:~$ date | tee file1 Mon 28 Nov 15:14:18 GMT 2016 trainee@debian8:~$ cat file1 Mon 28 Nov 15:14:18 GMT 2016
trainee@ubuntu1604:~$ date | tee file1 Mon 28 Nov 16:14:22 CET 2016 trainee@ubuntu1604:~$ cat file1 Mon 28 Nov 16:14:22 CET 2016
[trainee@centos7 ~]$ date | tee file1 Mon 28 Nov 16:14:24 CET 2016 [trainee@centos7 ~]$ cat file1 Mon 28 Nov 16:14:24 CET 2016
trainee@SLES12SP1:~> date | tee file1 Mon 28 Nov 16:14:43 CET 2016 trainee@SLES12SP1:~> cat file1 Mon 28 Nov 16:14:43 CET 2016
Alternatively, tee can be used to redirect to two files at the same time:
trainee@debian8:~$ date | tee fichier1 > fichier2 trainee@debian8:~$ cat fichier1 Mon 28 Nov 15:15:52 GMT 2016 trainee@debian8:~$ cat fichier2 Mon 28 Nov 15:15:52 GMT 2016
trainee@ubuntu1604:~$ date | tee fichier1 > fichier2 trainee@ubuntu1604:~$ cat fichier1 Mon 28 Nov 16:15:56 CET 2016 trainee@ubuntu1604:~$ cat fichier2 Mon 28 Nov 16:15:56 CET 2016
[trainee@centos7 ~]$ date | tee fichier1 > fichier2 [trainee@centos7 ~]$ cat fichier1 Mon 28 Nov 16:15:57 CET 2016 [trainee@centos7 ~]$ cat fichier2 Mon 28 Nov 16:15:57 CET 2016
trainee@SLES12SP1:~> date | tee fichier1 > fichier2 trainee@SLES12SP1:~> cat fichier1 Mon 28 Nov 16:16:15 CET 2016 trainee@SLES12SP1:~> cat fichier2 Mon 28 Nov 16:16:15 CET 2016
Important : The default action of the tee command is to overwrite the destination file. In order to append output to the same file, you need to use the -a switch.
Command substitution permits in-line execution of a command:
trainee@debian8:~$ echo date date trainee@debian8:~$ echo $(date) Mon 28 Nov 15:19:29 GMT 2016 trainee@debian8:~$ echo `date` Mon 28 Nov 15:19:30 GMT 2016
trainee@ubuntu1604:~$ echo date date trainee@ubuntu1604:~$ echo $(date) Mon 28 Nov 16:19:33 CET 2016 trainee@ubuntu1604:~$ echo `date` Mon 28 Nov 16:19:33 CET 2016
[trainee@centos7 ~]$ echo date date [trainee@centos7 ~]$ echo $(date) Mon 28 Nov 16:19:35 CET 2016 [trainee@centos7 ~]$ echo `date` Mon 28 Nov 16:19:35 CET 2016
trainee@SLES12SP1:~> echo date date trainee@SLES12SP1:~> echo $(date) Mon 28 Nov 16:19:53 CET 2016 trainee@SLES12SP1:~> echo `date` Mon 28 Nov 16:19:53 CET 2016
Commands can be grouped using brackets:
$ (ls -l; ps; who) > list
Conditional command execution can be obtained by using the exit status value and either && or ||.
For example,
The contents of a shell variable can be displayed on standard output using the echo command:
$ echo $VARIABLE [Enter]
Variable | Description |
---|---|
BASH | Complete path to current shell. |
BASH_VERSION | Shell version. |
EUID | EUID of the current user. |
UID | UID of the current user. |
PPID | PID of the parent of the current process. |
PWD | The current directory. |
OLDPWD | The previous current directory ( like the cd -command ). |
RANDOM | A random number between 0 and 32767. |
SECONDS | The numbers of seconds since the shell was started. |
LINES | The number of lines in a screen. |
COLUMNS | The number of columns in a screen . |
HISTFILE | The history file. |
HISTFILESIZE | The history file size. |
HISTSIZE | The number of commands that can be saved to the history file. |
HISTCMD | The current command's number in the History. |
HISTCONTROL | ignorespace or ignoredups or ignoreboth |
HOME | The user's home directory. |
HOSTTYPE | Machine type. |
OSTYPE | The OS type. |
The file containing the user's mail. | |
MAILCHECK | Frequency in seconds that a user's mail is checked. |
PATH | The paths to executables. |
PROMPT_COMMAND | Command executed before each prompt is displayed. |
PS1 | User's default prompt. |
PS2 | User's 2nd level default prompt. |
PS3 | User's 3rd level prompt. |
PS4 | User's 4th level prompt. |
SHELL | User's current shell. |
SHLVL | The number of shell instances. |
TMOUT | The number of seconds less 60 before an unused terminal gets sent the exit command. |
Internationalisation, also called i18n since there are 18 letters between the I and n, consists of modifying software so that it conforms to regional parameters:
Localisation, also called L10n since there are 10 letters between the L and n, consists of modifying the Internationalisation so that it conforms to a specific locale:
The most important variables are:
trainee@debian8:~$ echo $LC_ALL en_GB.UTF-8 trainee@debian8:~$ echo $LC_CTYPE trainee@debian8:~$ echo $LANG en_GB.UTF-8 trainee@debian8:~$ locale LANG=en_GB.UTF-8 LANGUAGE=en_GB:en LC_CTYPE="en_GB.UTF-8" LC_NUMERIC="en_GB.UTF-8" LC_TIME="en_GB.UTF-8" LC_COLLATE="en_GB.UTF-8" LC_MONETARY="en_GB.UTF-8" LC_MESSAGES="en_GB.UTF-8" LC_PAPER="en_GB.UTF-8" LC_NAME="en_GB.UTF-8" LC_ADDRESS="en_GB.UTF-8" LC_TELEPHONE="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" LC_IDENTIFICATION="en_GB.UTF-8" LC_ALL=en_GB.UTF-8
trainee@ubuntu1604:~$ echo $LC_ALL en_GB.UTF-8 trainee@ubuntu1604:~$ echo $LC_CTYPE trainee@ubuntu1604:~$ echo $LANG en_GB.UTF-8 trainee@ubuntu1604:~$ locale LANG=en_GB.UTF-8 LANGUAGE= LC_CTYPE="en_GB.UTF-8" LC_NUMERIC="en_GB.UTF-8" LC_TIME="en_GB.UTF-8" LC_COLLATE="en_GB.UTF-8" LC_MONETARY="en_GB.UTF-8" LC_MESSAGES="en_GB.UTF-8" LC_PAPER="en_GB.UTF-8" LC_NAME="en_GB.UTF-8" LC_ADDRESS="en_GB.UTF-8" LC_TELEPHONE="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" LC_IDENTIFICATION="en_GB.UTF-8" LC_ALL=en_GB.UTF-8
[trainee@centos7 ~]$ echo $LC_ALL en_GB.UTF-8 [trainee@centos7 ~]$ echo $LC_CTYPE [trainee@centos7 ~]$ echo $LANG en_GB.UTF-8 [trainee@centos7 ~]$ locale LANG=en_GB.UTF-8 LC_CTYPE="en_GB.UTF-8" LC_NUMERIC="en_GB.UTF-8" LC_TIME="en_GB.UTF-8" LC_COLLATE="en_GB.UTF-8" LC_MONETARY="en_GB.UTF-8" LC_MESSAGES="en_GB.UTF-8" LC_PAPER="en_GB.UTF-8" LC_NAME="en_GB.UTF-8" LC_ADDRESS="en_GB.UTF-8" LC_TELEPHONE="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" LC_IDENTIFICATION="en_GB.UTF-8" LC_ALL=en_GB.UTF-8
trainee@SLES12SP1:~> echo $LC_ALL en_GB.UTF-8 trainee@SLES12SP1:~> echo $LC_CTYPE trainee@SLES12SP1:~> echo $LANG en_GB.UTF-8 trainee@SLES12SP1:~> locale LANG=en_GB.UTF-8 LC_CTYPE="en_GB.UTF-8" LC_NUMERIC="en_GB.UTF-8" LC_TIME="en_GB.UTF-8" LC_COLLATE="en_GB.UTF-8" LC_MONETARY="en_GB.UTF-8" LC_MESSAGES="en_GB.UTF-8" LC_PAPER="en_GB.UTF-8" LC_NAME="en_GB.UTF-8" LC_ADDRESS="en_GB.UTF-8" LC_TELEPHONE="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" LC_IDENTIFICATION="en_GB.UTF-8" LC_ALL=en_GB.UTF-8
Variable | Description |
---|---|
$LINENO | Contains the current line number of the script or function being executed |
$$ | Contains the PID of the current process |
$PPID | Contains the PID of the parent of the current process |
$0 | Contains the name of the current script |
$1, $2 … | Contains respectively the 1st, 2nd etc arguments passed to the script |
$# | Contains the total number of arguments passed to the script |
$* | Contains all of the arguments passed to the script |
$@ | Contains all of the arguments passed to the script |
The env command can be used to run a program in a modified environment or just list the values of all environmental variables associated with the user calling the program env:
trainee@debian8:~$ env XDG_SESSION_ID=1 TERM=xterm-256color SHELL=/bin/bash SSH_CLIENT=10.0.2.2 44524 22 OLDPWD=/home/trainee/training SSH_TTY=/dev/pts/0 LC_ALL=en_GB.UTF-8 USER=trainee LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: MAIL=/var/mail/trainee PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/trainee LANG=en_GB.UTF-8 SHLVL=1 HOME=/home/trainee LANGUAGE=en_GB:en LOGNAME=trainee SSH_CONNECTION=10.0.2.2 44524 10.0.2.15 22 XDG_RUNTIME_DIR=/run/user/1000 _=/usr/bin/env
trainee@ubuntu1604:~$ env LC_PAPER=fr_FR.UTF-8 LC_ADDRESS=fr_FR.UTF-8 XDG_SESSION_ID=1 LC_MONETARY=fr_FR.UTF-8 TERM=xterm-256color SHELL=/bin/bash SSH_CLIENT=10.0.2.2 40266 22 LC_NUMERIC=fr_FR.UTF-8 OLDPWD=/home/trainee/training SSH_TTY=/dev/pts/8 LC_ALL=en_GB.UTF-8 USER=trainee LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36: LC_TELEPHONE=fr_FR.UTF-8 MAIL=/var/mail/trainee PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin QT_QPA_PLATFORMTHEME=appmenu-qt5 LC_IDENTIFICATION=fr_FR.UTF-8 PWD=/home/trainee LANG=en_US.UTF-8 LC_MEASUREMENT=fr_FR.UTF-8 SHLVL=1 HOME=/home/trainee LOGNAME=trainee SSH_CONNECTION=10.0.2.2 40266 10.0.2.15 22 LESSOPEN=| /usr/bin/lesspipe %s XDG_RUNTIME_DIR=/run/user/1000 LESSCLOSE=/usr/bin/lesspipe %s %s LC_TIME=fr_FR.UTF-8 LC_NAME=fr_FR.UTF-8 _=/usr/bin/env
[trainee@centos7 ~]$ env XDG_SESSION_ID=1 HOSTNAME=centos7.fenestros.loc SELINUX_ROLE_REQUESTED= TERM=xterm-256color SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=10.0.2.2 33896 22 SELINUX_USE_CURRENT_RANGE= SSH_TTY=/dev/pts/0 LC_ALL=en_GB.UTF-8 USER=trainee LS_COLORS=rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45: MAIL=/var/spool/mail/trainee PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/trainee/.local/bin:/home/trainee/bin PWD=/home/trainee LANG=fr_FR.UTF-8 SELINUX_LEVEL_REQUESTED= HISTCONTROL=ignoredups SHLVL=1 HOME=/home/trainee LOGNAME=trainee SSH_CONNECTION=10.0.2.2 33896 192.168.1.99 22 LESSOPEN=||/usr/bin/lesspipe.sh %s XDG_RUNTIME_DIR=/run/user/1000 _=/usr/bin/env OLDPWD=/home/trainee/training
trainee@SLES12SP1:~> env LESSKEY=/etc/lesskey.bin NNTPSERVER=news MANPATH=/usr/local/man:/usr/share/man XDG_SESSION_ID=1 HOSTNAME=SLES12SP1 XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB HOST=SLES12SP1 TERM=xterm-256color SHELL=/bin/bash PROFILEREAD=true HISTSIZE=1000 SSH_CLIENT=10.0.2.2 46258 22 MORE=-sl SSH_TTY=/dev/pts/0 LC_ALL=en_GB.UTF-8 USER=trainee LS_COLORS=no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.xz=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32: XNLSPATH=/usr/share/X11/nls QEMU_AUDIO_DRV=pa HOSTTYPE=x86_64 FROM_HEADER= PAGER=less CSHEDIT=emacs XDG_CONFIG_DIRS=/etc/xdg LIBGL_DEBUG=quiet MINICOM=-c on MAIL=/var/mail/trainee PATH=/home/trainee/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games CPU=x86_64 SSH_SENDS_LOCALE=yes INPUTRC=/home/trainee/.inputrc PWD=/home/trainee LANG=fr_FR.UTF-8 PYTHONSTARTUP=/etc/pythonstart GPG_TTY=/dev/pts/0 AUDIODRIVER=pulseaudio QT_SYSTEM_DIR=/usr/share/desktop-data SHLVL=1 HOME=/home/trainee ALSA_CONFIG_PATH=/etc/alsa-pulse.conf SDL_AUDIODRIVER=pulse LESS_ADVANCED_PREPROCESSOR=no OSTYPE=linux LS_OPTIONS=-N --color=tty -T 0 XCURSOR_THEME=DMZ WINDOWMANAGER=env GNOME_SHELL_SESSION_MODE=sle-classic gnome-session --session sle-classic G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252 LESS=-M -I -R MACHTYPE=x86_64-suse-linux LOGNAME=trainee XDG_DATA_DIRS=/usr/share SSH_CONNECTION=10.0.2.2 46258 10.0.2.15 22 LESSOPEN=lessopen.sh %s XDG_RUNTIME_DIR=/run/user/1000 NO_AT_BRIDGE=1 LESSCLOSE=lessclose.sh %s %s G_BROKEN_FILENAMES=1 COLORTERM=1 _=/usr/bin/env OLDPWD=/home/trainee/training
To run a program, such as xterm in a modified environment the command is:
$ env EDITOR=vim xterm
To view all the options of the bash shell, use the command set:
trainee@debian8:~$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
trainee@ubuntu1604:~$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
[trainee@centos7 ~]$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
trainee@SLES12SP1:~> set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
To turn on an option you need to specify which option as an argument to the previous command:
trainee@debian8:~$ set -o allexport trainee@debian8:~$ set -o allexport on braceexpand on ...
trainee@ubuntu1604:~$ set -o allexport trainee@ubuntu1604:~$ set -o allexport on braceexpand on ...
[trainee@centos7 ~]$ set -o allexport [trainee@centos7 ~]$ set -o allexport on braceexpand on ...
trainee@SLES12SP1:~> set -o allexport trainee@SLES12SP1:~> set -o allexport on braceexpand on ...
To turn off an option, use set with the +o option:
trainee@debian8:~$ set +o allexport trainee@debian8:~$ set -o allexport off braceexpand on ...
trainee@ubuntu1604:~$ set +o allexport trainee@ubuntu1604:~$ set -o allexport off braceexpand on ...
[trainee@centos7 ~]$ set +o allexport [trainee@centos7 ~]$ set -o allexport off braceexpand on ...
trainee@SLES12SP1:~> set +o allexport trainee@SLES12SP1:~> set -o allexport off braceexpand on ...
These are the most interesting options:
Option | Default value | Description |
---|---|---|
allexport | off | The shell automatically exports all variables |
emacs | on | emacs editing mode |
noclobber | off | Simple re-directions do not squash the target file if it exists |
noglob | off | Turns off special characters |
nounset | off | The shell will return an error if the variable is not set |
verbose | off | Echos back the typed command |
vi | off | vi editing mode |
trainee@debian8:~$ set -o noclobber trainee@debian8:~$ pwd > file -bash: file: cannot overwrite existing file trainee@debian8:~$ pwd > file -bash: file: cannot overwrite existing file trainee@debian8:~$ pwd >| file trainee@debian8:~$ set +o noclobber
trainee@ubuntu1604:~$ set -o noclobber trainee@ubuntu1604:~$ pwd > file trainee@ubuntu1604:~$ pwd > file -bash: file: cannot overwrite existing file trainee@ubuntu1604:~$ pwd >| file trainee@ubuntu1604:~$ set +o noclobber
[trainee@centos7 ~]$ set -o noclobber [trainee@centos7 ~]$ pwd > file -bash: file: cannot overwrite existing file [trainee@centos7 ~]$ pwd > file -bash: file: cannot overwrite existing file [trainee@centos7 ~]$ pwd >| file [trainee@centos7 ~]$ set +o noclobber
trainee@SLES12SP1:~> set -o noclobber trainee@SLES12SP1:~> pwd > file trainee@SLES12SP1:~> pwd > file -bash: file: cannot overwrite existing file trainee@SLES12SP1:~> pwd >| file trainee@SLES12SP1:~> set +o noclobber
Important : Note that the noclobber option can be overidden by using a pipe.
trainee@debian8:~$ set -o noglob trainee@debian8:~$ echo * * trainee@debian8:~$ set +o noglob trainee@debian8:~$ echo * aac abc bca codes Desktop Documents Downloads errorlog file file1 Music Pictures Public Templates training Videos vitext xyz
trainee@ubuntu1604:~$ set -o noglob trainee@ubuntu1604:~$ echo * * trainee@ubuntu1604:~$ set +o noglob trainee@ubuntu1604:~$ echo * aac abc bca codes Desktop Documents Downloads errorlog examples.desktop file file1 Music Pictures Public Templates training Videos vitext xyz
[trainee@centos7 ~]$ set -o noglob [trainee@centos7 ~]$ echo * * [trainee@centos7 ~]$ set +o noglob [trainee@centos7 ~]$ echo * aac abc bca codes Desktop Documents Downloads errorlog file file1 Music Pictures Public Templates training Videos vitext xyz
trainee@SLES12SP1:~> set -o noglob trainee@SLES12SP1:~> echo * * trainee@SLES12SP1:~> set +o noglob trainee@SLES12SP1:~> echo * aac abc bca bin codes Desktop Documents Downloads errorlog file file1 Music Pictures Public public_html Templates training Videos vitext xyz
Important : Note that metacharacters are turned off when the noglob option is set.
trainee@debian8:~$ set -o nounset trainee@debian8:~$ echo $FENESTROS -bash: FENESTROS: unbound variable trainee@debian8:~$ set +o nounset trainee@debian8:~$ echo $FENESTROS trainee@debian8:~$
trainee@ubuntu1604:~$ set -o nounset trainee@ubuntu1604:~$ echo $FENESTROS -bash: FENESTROS: unbound variable trainee@ubuntu1604:~$ set +o nounset trainee@ubuntu1604:~$ echo $FENESTROS trainee@ubuntu1604:~$
[trainee@centos7 ~]$ set -o nounset [trainee@centos7 ~]$ echo $FENESTROS -bash: FENESTROS: unbound variable [trainee@centos7 ~]$ set +o nounset [trainee@centos7 ~]$ echo $FENESTROS [trainee@centos7 ~]$
trainee@SLES12SP1:~> set -o nounset trainee@SLES12SP1:~> echo $FENESTROS -bash: FENESTROS: unbound variable trainee@SLES12SP1:~> set +o nounset trainee@SLES12SP1:~> echo $FENESTROS trainee@SLES12SP1:~>
Important : Note that the inexistant variable $FENESTROS is identified as such when the nounset option is set.
A script is a text file that is read by the system and it's contents executed. There are five ways to execute a script:
By stipulating the shell that will execute the script:
/bin/bash myscript
by a reverse redirection:
/bin/bash < myscript
By calling the script by it's name, provided that the script is executable and that it resides in a directory specified by your path :
myscript
By placing yourself in the directory where the script resides and using one of the two following possibilities :
. myscript et ./myscript
Important: In the first case the script is executed in the parent shell. In the second case the script is executed in a child shell.
Comments in a script are lines starting with #. However, each script starts with a pseudo-comment that informs the system which shell should be used to execute the script:
#!/bin/sh
Since a script in it's simplest form is a list of commands that are sequentially executed, it is often useful to test those command prior to writing the script> Linux has a command that can help you debug a future script. The script command can be used to generate a log file, called typescript, that contains a record of everything occurred on standard output. To exit the recording mode, use exit:
trainee@debian8:~$ script Script started, file is typescript trainee@debian8:~$ pwd /home/trainee trainee@debian8:~$ ls aac bca Desktop Downloads fichier1 file Music Public training Videos xyz abc codes Documents errorlog fichier2 file1 Pictures Templates typescript vitext trainee@debian8:~$ exit exit Script done, file is typescript trainee@debian8:~$ cat typescript Script started on Tue 29 Nov 2016 02:56:33 GMT trainee@debian8:~$ pwd /home/trainee trainee@debian8:~$ ls aac bca Desktop Downloads fichier1 file Music Public training Videos xyz abc codes Documents errorlog fichier2 file1 Pictures Templates typescript vitext trainee@debian8:~$ exit exit Script done on Tue 29 Nov 2016 02:56:44 GMT
trainee@ubuntu1604:~$ script Script started, file is typescript trainee@ubuntu1604:~$ pwd /home/trainee trainee@ubuntu1604:~$ ls aac codes Downloads fichier1 file1 Public typescript xyz abc Desktop errorlog fichier2 Music Templates Videos bca Documents examples.desktop file Pictures training vitext trainee@ubuntu1604:~$ exit exit Script done, file is typescript trainee@ubuntu1604:~$ cat typescript Script started on Tue 29 Nov 2016 03:57:47 CET trainee@ubuntu1604:~$ pwd /home/trainee trainee@ubuntu1604:~$ ls aac codes Downloads fichier1 file1 Public typescript xyz abc Desktop errorlog fichier2 Music Templates Videos bca Documents examples.desktop file Pictures training vitext trainee@ubuntu1604:~$ exit exit Script done on Tue 29 Nov 2016 03:57:58 CET
[trainee@centos7 ~]$ script Script started, file is typescript [trainee@centos7 ~]$ pwd /home/trainee [trainee@centos7 ~]$ ls aac bca Desktop Downloads fichier1 file Music Public training Videos xyz abc codes Documents errorlog fichier2 file1 Pictures Templates typescript vitext [trainee@centos7 ~]$ exit exit Script done, file is typescript [trainee@centos7 ~]$ cat typescript Script started on Tue 29 Nov 2016 03:58:33 CET [trainee@centos7 ~]$ pwd /home/trainee [trainee@centos7 ~]$ ls aac bca Desktop Downloads fichier1 file Music Public training Videos xyz abc codes Documents errorlog fichier2 file1 Pictures Templates typescript vitext [trainee@centos7 ~]$ exit exit Script done on Tue 29 Nov 2016 03:58:40 CET
trainee@SLES12SP1:~> script Script started, file is typescript trainee@SLES12SP1:~> pwd /home/trainee trainee@SLES12SP1:~> ls aac bin Documents fichier1 file1 Public training vitext abc codes Downloads fichier2 Music public_html typescript xyz bca Desktop errorlog file Pictures Templates Videos trainee@SLES12SP1:~> exit exit Script done, file is typescript trainee@SLES12SP1:~> cat typescript Script started on Tue 29 Nov 2016 03:59:24 CET trainee@SLES12SP1:~> pwd /home/trainee trainee@SLES12SP1:~> ls aac bin Documents fichier1 file1 Public training vitext abc codes Downloads fichier2 Music public_html typescript xyz bca Desktop errorlog file Pictures Templates Videos trainee@SLES12SP1:~> exit exit Script done on Tue 29 Nov 2016 03:59:31 CET
Lets start by creating a simple script called myscript:
$ vi myscript [Enter]
Edit the file as follows:
pwd ls
Important: Note that in the above example, the script does not start with a pseudo-comment. As a result, the script will be executed by the shell of the user that invokes it unless a different shell is specified.
Save the file and use the five ways to execute it.
As an argument de /bin/bash:
trainee@debian8:~$ vi myscript trainee@debian8:~$ /bin/bash myscript /home/trainee aac codes Downloads fichier2 myscript Public typescript xyz abc Desktop errorlog file Music Templates Videos bca Documents fichier1 file1 Pictures training vitext
trainee@ubuntu1604:~$ vi myscript trainee@ubuntu1604:~$ /bin/bash myscript /home/trainee aac codes Downloads fichier1 file1 Pictures training vitext abc Desktop errorlog fichier2 myscript Public typescript xyz bca Documents examples.desktop file Music Templates Videos
[trainee@centos7 ~]$ vi myscript [trainee@centos7 ~]$ /bin/bash myscript /home/trainee aac codes Downloads fichier2 myscript Public typescript xyz abc Desktop errorlog file Music Templates Videos bca Documents fichier1 file1 Pictures training vitext
trainee@SLES12SP1:~> vi myscript trainee@SLES12SP1:~> /bin/bash myscript /home/trainee aac bin Documents fichier1 file1 Pictures Templates Videos abc codes Downloads fichier2 myscript Public training vitext bca Desktop errorlog file Music public_html typescript xyz
Using a redirection:
trainee@debian8:~$ /bin/bash < myscript /home/trainee aac codes Downloads fichier2 myscript Public typescript xyz abc Desktop errorlog file Music Templates Videos bca Documents fichier1 file1 Pictures training vitext
trainee@ubuntu1604:~$ /bin/bash < myscript /home/trainee aac codes Downloads fichier1 file1 Pictures training vitext abc Desktop errorlog fichier2 myscript Public typescript xyz bca Documents examples.desktop file Music Templates Videos
[trainee@centos7 ~]$ /bin/bash < myscript /home/trainee aac codes Downloads fichier2 myscript Public typescript xyz abc Desktop errorlog file Music Templates Videos bca Documents fichier1 file1 Pictures training vitext
trainee@SLES12SP1:~> /bin/bash < myscript /home/trainee aac bin Documents fichier1 file1 Pictures Templates Videos abc codes Downloads fichier2 myscript Public training vitext bca Desktop errorlog file Music public_html typescript xyz
In order to be able to call the script by it's name from another directory, such as /tmp, you need to move the script into the /home/trainee/bin directory and make it executable. Note that in this case, the the value of the environmental variable $PATH should contain a reference to /home/trainee/bin:
trainee@debian8:~$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
trainee@ubuntu1604:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
[trainee@centos7 ~]$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/trainee/.local/bin:/home/trainee/bin
trainee@SLES12SP1:~> echo $PATH /home/trainee/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
As you can see, in the case of Debian and Ubuntu, this is not the case. The reason for this becomes apparent when viewing the contents of the .profile file in /home/trainee:
trainee@debian8:~$ cat .profile # ~/.profile: executed by the command interpreter for login shells. ... # set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
trainee@ubuntu1604:~$ cat .profile # ~/.profile: executed by the command interpreter for login shells. ... # set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
As you can see PATH is set so it includes the user's private bin only if the directory exists:
# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
To fix the value of the PATH variable, create the $HOME/bin directory and re-load the .profile file:
trainee@debian8:~$ mkdir bin trainee@debian8:~$ source .profile trainee@debian8:~$ echo $PATH /home/trainee/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
trainee@ubuntu1604:~$ mkdir bin trainee@ubuntu1604:~$ source .profile trainee@ubuntu1604:~$ echo $PATH /home/trainee/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
In the case of RHEL/CentOS, even though PATH contains $HOME/bin, the directory is not present:
[trainee@centos7 ~]$ ls aac codes Downloads fichier2 myscript Public typescript xyz abc Desktop errorlog file Music Templates Videos bca Documents fichier1 file1 Pictures training vitext
So you need to create the directory:
[trainee@centos7 ~]$ mkdir bin
Now you need to move the script to $HOME/bin and make it executable:
trainee@debian8:~$ mv myscript ~/bin trainee@debian8:~$ chmod u+x ~/bin/myscript
trainee@ubuntu1604:~$ mv myscript ~/bin trainee@ubuntu1604:~$ chmod u+x ~/bin/myscript
[trainee@centos7 ~]$ mv myscript ~/bin [trainee@centos7 ~]$ chmod u+x ~/bin/myscript
trainee@SLES12SP1:~> mv myscript ~/bin trainee@SLES12SP1:~> chmod u+x ~/bin/myscript
Move to /tmp and can call the script by just using it's name:
trainee@debian8:/tmp$ myscript /tmp hsperfdata_root pulse-PKdhtXMmr18n
trainee@ubuntu1604:/tmp$ myscript /tmp hsperfdata_root systemd-private-2596faf2be00473d9dc6da53af5711d5-colord.service-K4xRp2 systemd-private-2596faf2be00473d9dc6da53af5711d5-rtkit-daemon.service-iKio6G systemd-private-2596faf2be00473d9dc6da53af5711d5-systemd-timesyncd.service-AlOq91
[trainee@centos7 tmp]$ myscript /tmp hsperfdata_root systemd-private-e526abcf335b40949dfc725f28456502-cups.service-u0xGiL
trainee@SLES12SP1:/tmp> myscript /tmp hsperfdata_root inode managera1411267841657715235client managera3336001029897679475server managera4847938942232964844client managera5050357016347721452server systemd-private-04f820fa26c745be8ddba814c6292f21-rtkit-daemon.service-o4lKP5 systemicontmp5578677472245134133dat systemicontmp7082392205020802884dat
Now move back to ~/bin and use the following two commands to execute myscript:
trainee@debian8:/tmp$ cd ~/bin trainee@debian8:~/bin$ ./myscript /home/trainee/bin myscript trainee@debian8:~/bin$ . myscript /home/trainee/bin myscript
trainee@ubuntu1604:/tmp$ cd ~/bin trainee@ubuntu1604:~/bin$ ./myscript /home/trainee/bin myscript trainee@ubuntu1604:~/bin$ . myscript /home/trainee/bin myscript
[trainee@centos7 tmp]$ cd ~/bin [trainee@centos7 bin]$ ./myscript /home/trainee/bin myscript [trainee@centos7 bin]$ . myscript /home/trainee/bin myscript
trainee@SLES12SP1:/tmp> cd ~/bin trainee@SLES12SP1:~/bin> ./myscript /home/trainee/bin myscript trainee@SLES12SP1:~/bin> . myscript /home/trainee/bin myscript
To do: Note the difference in the output of these two commands and explain that difference.
The read command reads the standard input and stores the information in the variables that are specified as arguments. The separator between fields is a space, a tabultaion or a carriage return:
trainee@debian8:~/bin$ read var1 var2 var3 var4 fenestros edu is great! trainee@debian8:~/bin$ echo $var1 fenestros trainee@debian8:~/bin$ echo $var2 edu trainee@debian8:~/bin$ echo $var3 is trainee@debian8:~/bin$ echo $var4 great!
trainee@ubuntu1604:~/bin$ read var1 var2 var3 var4 fenestros edu is great! trainee@ubuntu1604:~/bin$ echo $var1 fenestros trainee@ubuntu1604:~/bin$ echo $var2 edu trainee@ubuntu1604:~/bin$ echo $var3 is trainee@ubuntu1604:~/bin$ echo $var4 great!
[trainee@centos7 bin]$ read var1 var2 var3 var4 fenestros edu is great! [trainee@centos7 bin]$ echo $var1 fenestros [trainee@centos7 bin]$ echo $var2 edu [trainee@centos7 bin]$ echo $var3 is [trainee@centos7 bin]$ echo $var4 great!
trainee@SLES12SP1:~/bin> read var1 var2 var3 var4 fenestros edu is great! trainee@SLES12SP1:~/bin> echo $var1 fenestros trainee@SLES12SP1:~/bin> echo $var2 edu trainee@SLES12SP1:~/bin> echo $var3 is trainee@SLES12SP1:~/bin> echo $var4 great!
Important: Note that each field has been placed in a seperate variable. Note also that by convention, user declared variables are in lower case in order to distinguish them from system variables.
trainee@debian8:~/bin$ read var1 var2 fenestros edu is great! trainee@debian8:~/bin$ echo $var1 fenestros trainee@debian8:~/bin$ echo $var2 edu is great!
trainee@ubuntu1604:~/bin$ read var1 var2 fenestros edu is great! trainee@ubuntu1604:~/bin$ echo $var1 fenestros trainee@ubuntu1604:~/bin$ echo $var2 edu is great!
[trainee@centos7 bin]$ read var1 var2 fenestros edu is great! [trainee@centos7 bin]$ echo $var1 fenestros [trainee@centos7 bin]$ echo $var2 edu is great!
trainee@SLES12SP1:~/bin> read var1 var2 fenestros edu is great! trainee@SLES12SP1:~/bin> echo $var1 fenestros trainee@SLES12SP1:~/bin> echo $var2 edu is great!
Important: Note that in this case, $var2 contains three fields.
The contents of a variable can also be empty:
trainee@debian8:~/bin$ read var
↵ Enter
trainee@debian8:~/bin$ echo $? 0 trainee@debian8:~/bin$ echo $var trainee@debian8:~/bin$
trainee@ubuntu1604:~/bin$ read var
↵ Enter
trainee@ubuntu1604:~/bin$ echo $? 0 trainee@ubuntu1604:~/bin$ echo $var trainee@ubuntu1604:~/bin$
[trainee@centos7 bin]$ read var
↵ Enter
[trainee@centos7 bin]$ echo $? 0 [trainee@centos7 bin]$ echo $var [trainee@centos7 bin]$
trainee@SLES12SP1:~/bin> read var
↵ Enter
trainee@SLES12SP1:~/bin> echo $? 0 trainee@SLES12SP1:~/bin> echo $var trainee@SLES12SP1:~/bin>
But not null:
trainee@debian8:~/bin$ read var
Ctrl+D
trainee@debian8:~/bin$ echo $? 1 trainee@debian8:~/bin$ echo $var trainee@debian8:~/bin$
trainee@ubuntu1604:~/bin$ read var
Ctrl+D
trainee@ubuntu1604:~/bin$ echo $? 1 trainee@ubuntu1604:~/bin$ echo $var trainee@ubuntu1604:~/bin$
[trainee@centos7 bin]$ read var
Ctrl+D
[trainee@centos7 bin]$ echo $? 1 [trainee@centos7 bin]$ echo $var [trainee@centos7 bin]$
trainee@SLES12SP1:~/bin> read var
Ctrl+D
trainee@SLES12SP1:~/bin> echo $? 1 trainee@SLES12SP1:~/bin> echo $var trainee@SLES12SP1:~/bin>
The IFS variable contains the default separator characters: SpaceBar, Tab ⇆ and ↵ Enter:
trainee@debian8:~/bin$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
trainee@ubuntu1604:~/bin$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
[trainee@centos7 bin]$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
trainee@SLES12SP1:~/bin> echo "$IFS" | od -c 0000000 \t \n \n 0000004
Important: The od command (Octal Dump) returns the contents of a file in octal format. The -c switch prints to standard output any ASCII characters or backslashes contained within the file.
It is possible to change the contents of this variable:
trainee@debian8:~/bin$ OLDIFS="$IFS" trainee@debian8:~/bin$ IFS=":" trainee@debian8:~/bin$ echo "$IFS" | od -c 0000000 : \n 0000002
trainee@ubuntu1604:~/bin$ OLDIFS="$IFS" trainee@ubuntu1604:~/bin$ IFS=":" trainee@ubuntu1604:~/bin$ echo "$IFS" | od -c 0000000 : \n 0000002
[trainee@centos7 bin]$ OLDIFS="$IFS" [trainee@centos7 bin]$ IFS=":" [trainee@centos7 bin]$ echo "$IFS" | od -c 0000000 : \n 0000002
trainee@SLES12SP1:~/bin> OLDIFS="$IFS" trainee@SLES12SP1:~/bin> IFS=":" trainee@SLES12SP1:~/bin> echo "$IFS" | od -c 0000000 : \n 0000002
Now test the new configuration:
trainee@debian8:~/bin$ read var1 var2 var3 fenestros:edu is:great! trainee@debian8:~/bin$ echo $var1 fenestros trainee@debian8:~/bin$ echo $var2 edu is trainee@debian8:~/bin$ echo $var3 great!
trainee@ubuntu1604:~/bin$ read var1 var2 var3 fenestros:edu is:great! trainee@ubuntu1604:~/bin$ echo $var1 fenestros trainee@ubuntu1604:~/bin$ echo $var2 edu is trainee@ubuntu1604:~/bin$ echo $var3 great!
[trainee@centos7 bin]$ read var1 var2 var3 fenestros:edu is:great! [trainee@centos7 bin]$ echo $var1 fenestros [trainee@centos7 bin]$ echo $var2 edu is [trainee@centos7 bin]$ echo $var3 great!
trainee@SLES12SP1:~/bin> read var1 var2 var3 fenestros:edu is:great! trainee@SLES12SP1:~/bin> echo $var1 fenestros trainee@SLES12SP1:~/bin> echo $var2 edu is trainee@SLES12SP1:~/bin> echo $var3 great!
Restore the old value of IFS before proceeding further: IFS=“$OLDIFS”
trainee@debian8:~/bin$ IFS="$OLDIFS" trainee@debian8:~/bin$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
trainee@ubuntu1604:~/bin$ IFS="$OLDIFS" trainee@ubuntu1604:~/bin$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
[trainee@centos7 bin]$ IFS="$OLDIFS" [trainee@centos7 bin]$ echo "$IFS" | od -c 0000000 \t \n \n 0000004
trainee@SLES12SP1:~/bin> IFS="$OLDIFS" trainee@SLES12SP1:~/bin> echo "$IFS" | od -c 0000000 \t \n \n 0000004
The test command uses two forms:
test expression
or
[SpaceBarexpressionSpaceBar]
Test | Description |
---|---|
-f file | Returns true if file is an ordinary file |
-d file | Returns true if file is a directory |
-r file | Returns true if user can read file |
-w file | Returns true if user can write file |
-x file | Returns true if user can execute file |
-e file | Returns true if file exists |
-s file | Returns true if file is not empty |
file1 -nt file2 | Returns true if file1 is newer than file2 |
file1 -ot file2 | Returns true if file1 is older than file2 |
file1 -ef file2 | Returns true if file1 is identical to file2 |
Test whether the a100 file is an ordinary file:
trainee@debian8:~/bin$ cd ../training/ trainee@debian8:~/training$ test -f a100 trainee@debian8:~/training$ echo $? 0 trainee@debian8:~/training$ [ -f a100 ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/bin$ cd ../training/ trainee@ubuntu1604:~/training$ test -f a100 trainee@ubuntu1604:~/training$ echo $? 0 trainee@ubuntu1604:~/training$ [ -f a100 ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 bin]$ cd ../training/ [trainee@centos7 training]$ test -f a100 [trainee@centos7 training]$ echo $? 0 [trainee@centos7 training]$ [ -f a100 ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/bin> cd ../training/ trainee@SLES12SP1:~/training> test -f a100 trainee@SLES12SP1:~/training> echo $? 0 trainee@SLES12SP1:~/training> [ -f a100 ] trainee@SLES12SP1:~/training> echo $? 0
Important: The value contained in $? is 0. This indicates true.
Test whether the a101 file is an ordinary file:
trainee@debian8:~/training$ [ -f a101 ] trainee@debian8:~/training$ echo $? 1
trainee@ubuntu1604:~/training$ [ -f a101 ] trainee@ubuntu1604:~/training$ echo $? 1
[trainee@centos7 training]$ [ -f a101 ] [trainee@centos7 training]$ echo $? 1
trainee@SLES12SP1:~/training> [ -f a101 ] trainee@SLES12SP1:~/training> echo $? 1
Important: The value contained in $? is 1. This indicates false. This is obvious since a101 does not exist.
Test whether /home/trainee/training is a directory:
trainee@debian8:~/training$ [ -d /home/trainee/training ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ [ -d /home/trainee/training ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ [ -d /home/trainee/training ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> [ -d /home/trainee/training ] trainee@SLES12SP1:~/training> echo $? 0
Important: The value contained in $? is 0. This indicates true.
Test | Description |
---|---|
-n string | Returns true if string is not zero in length |
-z string | Returns true if string is zero in length |
string1 = string2 | Returns true if string1 is equal to string2 |
string1 != string2 | Returns true if string1 is different to string2 |
string1 | Returns true if string1 is not empty |
Test whether two strings are indentical:
trainee@debian8:~/training$ string1="root" trainee@debian8:~/training$ string2="fenestros" trainee@debian8:~/training$ [ $string1 = $string2 ] trainee@debian8:~/training$ echo $? 1
trainee@ubuntu1604:~/training$ string1="root" trainee@ubuntu1604:~/training$ string2="fenestros" trainee@ubuntu1604:~/training$ [ $string1 = $string2 ] trainee@ubuntu1604:~/training$ echo $? 1
[trainee@centos7 training]$ string1="root" [trainee@centos7 training]$ string2="fenestros" [trainee@centos7 training]$ [ $string1 = $string2 ] [trainee@centos7 training]$ echo $? 1
trainee@SLES12SP1:~/training> string1="root" trainee@SLES12SP1:~/training> string2="fenestros" trainee@SLES12SP1:~/training> [ $string1 = $string2 ] trainee@SLES12SP1:~/training> echo $? 1
Important: The value contained in $? is 1. This indicates false.
Test if string1 is not zero in length:
trainee@debian8:~/training$ [ -n $string1 ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ [ -n $string1 ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ [ -n $string1 ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> [ -n $string1 ] trainee@SLES12SP1:~/training> echo $? 0
Important: The value contained in $? is 0. This indicates true.
Test if string1 is is zero in length:
trainee@debian8:~/training$ [ -z $string1 ] trainee@debian8:~/training$ echo $? 1
trainee@ubuntu1604:~/training$ [ -z $string1 ] trainee@ubuntu1604:~/training$ echo $? 1
[trainee@centos7 training]$ [ -z $string1 ] [trainee@centos7 training]$ echo $? 1
trainee@SLES12SP1:~/training> [ -z $string1 ] trainee@SLES12SP1:~/training> echo $? 1
Important: The value contained in $? is 1. This indicates false.
Test | Description |
---|---|
value1 -eq value2 | Returns true if value1 is equal to value2 |
value1 -ne value2 | Returns true if value1 is not equal to value2 |
value1 -lt value2 | Returns true if value1 is less than value2 |
value1 -le value2 | Returns true if value1 is less than or equal to value2 |
value1 -gt value2 | Returns true if value1 is greater than value2 |
value1 -ge value2 | Returns true if value1 is greater than or equal to value2 |
Compare the two numbers value1 and value2 :
trainee@debian8:~/training$ read value1 35 trainee@debian8:~/training$ read value2 23 trainee@debian8:~/training$ [ $value1 -lt $value2 ] trainee@debian8:~/training$ echo $? 1 trainee@debian8:~/training$ [ $value2 -lt $value1 ] trainee@debian8:~/training$ echo $? 0 trainee@debian8:~/training$ [ $value2 -eq $value1 ] trainee@debian8:~/training$ echo $? 1
trainee@ubuntu1604:~/training$ read value1 35 trainee@ubuntu1604:~/training$ read value2 23 trainee@ubuntu1604:~/training$ [ $value1 -lt $value2 ] trainee@ubuntu1604:~/training$ echo $? 1 trainee@ubuntu1604:~/training$ [ $value2 -lt $value1 ] trainee@ubuntu1604:~/training$ echo $? 0 trainee@ubuntu1604:~/training$ [ $value2 -eq $value1 ] trainee@ubuntu1604:~/training$ echo $? 1
[trainee@centos7 training]$ read value1 35 [trainee@centos7 training]$ read value2 23 [trainee@centos7 training]$ [ $value1 -lt $value2 ] [trainee@centos7 training]$ echo $? 1 [trainee@centos7 training]$ [ $value2 -lt $value1 ] [trainee@centos7 training]$ echo $? 0 [trainee@centos7 training]$ [ $value2 -eq $value1 ] [trainee@centos7 training]$ echo $? 1
trainee@SLES12SP1:~/training> read value1 35 trainee@SLES12SP1:~/training> read value2 23 trainee@SLES12SP1:~/training> [ $value1 -lt $value2 ] trainee@SLES12SP1:~/training> echo $? 1 trainee@SLES12SP1:~/training> [ $value2 -lt $value1 ] trainee@SLES12SP1:~/training> echo $? 0 trainee@SLES12SP1:~/training> [ $value2 -eq $value1 ] trainee@SLES12SP1:~/training> echo $? 1
Test | Description |
---|---|
!expression | Returns true if expression is false |
expression1 -a expression2 | Represents a logical OR between expression1 and expression2 |
expression1 -o expression2 | Represents a logical AND between expression1 and expression2 |
\(expression\) | Parenthesis let you group together expressions |
Test if $file is not a directory:
trainee@debian8:~/training$ file=a1OO trainee@debian8:~/training$ [ ! -d $file ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ file=a1OO trainee@ubuntu1604:~/training$ [ ! -d $file ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ file=a1OO [trainee@centos7 training]$ [ ! -d $file ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> file=a1OO trainee@SLES12SP1:~/training> [ ! -d $file ] trainee@SLES12SP1:~/training> echo $? 0
Test if $directory is a directory and if trainee can cd into it:
trainee@debian8:~/training$ directory=/usr trainee@debian8:~/training$ [ -d $directory -a -x $directory ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ directory=/usr trainee@ubuntu1604:~/training$ [ -d $directory -a -x $directory ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ directory=/usr [trainee@centos7 training]$ [ -d $directory -a -x $directory ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> directory=/usr trainee@SLES12SP1:~/training> [ -d $directory -a -x $directory ] trainee@SLES12SP1:~/training> echo $? 0
Test if trainee has the write permission for the a100 file and test if /usr is a directory or test if /tmp is a directory:
trainee@debian8:~/training$ [ -w a100 -a \( -d /usr -o -d /tmp \) ] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ [ -w a100 -a \( -d /usr -o -d /tmp \) ] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ [ -w a100 -a \( -d /usr -o -d /tmp \) ] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> [ -w a100 -a \( -d /usr -o -d /tmp \) ] trainee@SLES12SP1:~/training> echo $? 0
Test | Description |
---|---|
-o option | Returns true if the shell option “option” is on |
trainee@debian8:~/training$ [ -o allexport ] trainee@debian8:~/training$ echo $? 1
trainee@ubuntu1604:~/training$ [ -o allexport ] trainee@ubuntu1604:~/training$ echo $? 1
[trainee@centos7 training]$ [ -o allexport ] [trainee@centos7 training]$ echo $? 1
trainee@SLES12SP1:~/training> [ -o allexport ] trainee@SLES12SP1:~/training> echo $? 1
The [[SpaceBarexpressionSpaceBar]] command is an improved test command with some minor changes to syntax:
Test | Description |
---|---|
expression1 && expression2 | Represents a logical OR between expression1 and expression2 |
expression1 || expression2 | Represents a logical AND between expression1 and expression2 |
(expression) | Parenthesis let you group together expressions |
and some additional operators :
Test | Description |
---|---|
string = model | Returns true if string corresponds to model |
string != model | Returns true if string does not correspond to model |
string1 < string2 | Returns true if string1 is lexicographically before string2 |
string1 > string2 | Returns true if string1 is lexicographically after string2 |
Test if trainee has the write permission for the a100 file and test if /usr is a directory or test if /tmp is a directory:
trainee@debian8:~/training$ [[ -w a100 && ( -d /usr || -d /tmp ) ]] trainee@debian8:~/training$ echo $? 0
trainee@ubuntu1604:~/training$ [[ -w a100 && ( -d /usr || -d /tmp ) ]] trainee@ubuntu1604:~/training$ echo $? 0
[trainee@centos7 training]$ [[ -w a100 && ( -d /usr || -d /tmp ) ]] [trainee@centos7 training]$ echo $? 0
trainee@SLES12SP1:~/training> [[ -w a100 && ( -d /usr || -d /tmp ) ]] trainee@SLES12SP1:~/training> echo $? 0
Operator | Description |
---|---|
Command1 && Command2 | Command2 is executed if the exit code of Command1 is zero |
Command1 || Command2 | Command2 is executed is the exit code of Command1 is not zero |
trainee@debian8:~/training$ [[ -d /root ]] && echo "The root directory exists" The root directory exists trainee@debian8:~/training$ [[ -d /root ]] || echo "The root directory exists" trainee@debian8:~/training$
trainee@ubuntu1604:~/training$ [[ -d /root ]] && echo "The root directory exists" The root directory exists trainee@ubuntu1604:~/training$ [[ -d /root ]] || echo "The root directory exists" trainee@ubuntu1604:~/training$
[trainee@centos7 training]$ [[ -d /root ]] && echo "The root directory exists" The root directory exists [trainee@centos7 training]$ [[ -d /root ]] || echo "The root directory exists" [trainee@centos7 training]$
trainee@SLES12SP1:~/training> [[ -d /root ]] && echo "The root directory exists" The root directory exists trainee@SLES12SP1:~/training> [[ -d /root ]] || echo "The root directory exists" trainee@SLES12SP1:~/training>
Theexpr command's syntax is as follows :
expr SpaceBar number1 SpaceBar operator SpaceBar number2 SpaceBar
ou
expr Tab ⇆ number1 Tab operator Tab ⇆ number2 ↵ Enter
ou
expr SpaceBar string SpaceBar : SpaceBar regular_expression SpaceBar
or
expr Tab ⇆ string Tab ⇆ : Tab ⇆ regular_expression ↵ Enter
Operator | Description |
---|---|
+ | Addition |
- | Subtraction |
\* | Multiplication |
/ | Division |
% | Modulo |
\( \) | Parentheses |
Operator | Description |
---|---|
\< | Less than |
\<= | Less than or equal to |
\> | Greater then |
\>= | Greater then or equal to |
= | Equal to |
!= | Not equal to |
Operator | Description |
---|---|
\| | Logical OR |
\& | Logical AND |
Add two to the value of $x:
trainee@debian8:~/training$ x=2 trainee@debian8:~/training$ expr $x + 2 4
trainee@ubuntu1604:~/training$ x=2 trainee@ubuntu1604:~/training$ expr $x + 2 4
[trainee@centos7 training]$ x=2 [trainee@centos7 training]$ expr $x + 2 4
trainee@SLES12SP1:~/training> x=2 trainee@SLES12SP1:~/training> expr $x + 2 4
If the surrounding spaces are removed, the result is completely different:
trainee@debian8:~/training$ expr $x+2 2+2
trainee@ubuntu1604:~/training$ expr $x+2 2+2
[trainee@centos7 training]$ expr $x+2 2+2
trainee@SLES12SP1:~/training> expr $x+2 2+2
Certain operators need to be protected:
trainee@debian8:~/training$ expr $x * 2 expr: syntax error trainee@debian8:~/training$ expr $x \* 2 4
trainee@ubuntu1604:~/training$ expr $x * 2 expr: syntax error trainee@ubuntu1604:~/training$ expr $x \* 2 4
[trainee@centos7 training]$ expr $x * 2 expr: syntax error [trainee@centos7 training]$ expr $x \* 2 4
trainee@SLES12SP1:~/training> expr $x * 2 expr: syntax error trainee@SLES12SP1:~/training> expr $x \* 2 4
Now put the result of a calculation in a variable:
trainee@debian8:~/training$ resultat=`expr $x + 10` trainee@debian8:~/training$ echo $resultat 12
trainee@ubuntu1604:~/training$ resultat=`expr $x + 10` trainee@ubuntu1604:~/training$ echo $resultat 12
[trainee@centos7 training]$ resultat=`expr $x + 10` [trainee@centos7 training]$ echo $resultat 12
trainee@SLES12SP1:~/training> resultat=`expr $x + 10` trainee@SLES12SP1:~/training> echo $resultat 12
The let command is equivalent to ((expression)). The ((expression)) command provides the following additional features when compared with the expr command :
Operator | Description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulo |
^ | Power |
Operator | Description |
---|---|
< | Less than |
<= | Less than or equal to |
> | Greater then |
>= | Greater then or equal to |
== | Equal |
!= | Not Equal |
Operator | Description |
---|---|
&& | Logical AND |
|| | Logical OR |
! | Logical negation |
Opérateur | Description |
---|---|
~ | Binary negation |
>> | décalage binaire à droite |
<< | décalage binaire à gauche |
& | Binary AND |
| | Binary OR |
^ | Exclusive binary OR |
trainee@debian8:~/training$ x=2 trainee@debian8:~/training$ ((x=$x+10)) trainee@debian8:~/training$ echo $x 12 trainee@debian8:~/training$ ((x=$x+20)) trainee@debian8:~/training$ echo $x 32
trainee@ubuntu1604:~/training$ x=2 trainee@ubuntu1604:~/training$ ((x=$x+10)) trainee@ubuntu1604:~/training$ echo $x 12 trainee@ubuntu1604:~/training$ ((x=$x+20)) trainee@ubuntu1604:~/training$ echo $x 32
[trainee@centos7 training]$ x=2 [trainee@centos7 training]$ ((x=$x+10)) [trainee@centos7 training]$ echo $x 12 [trainee@centos7 training]$ ((x=$x+20)) [trainee@centos7 training]$ echo $x 32
trainee@SLES12SP1:~/training> x=2 trainee@SLES12SP1:~/training> ((x=$x+10)) trainee@SLES12SP1:~/training> echo $x 12 trainee@SLES12SP1:~/training> ((x=$x+20)) trainee@SLES12SP1:~/training> echo $x 32
The syntax is as follows:
if condition then command(s) else command(s) fi
or:
if condition then command(s) command(s) fi
or finally:
if condition then command(s) elif condition then command(s) elif condition then command(s) else command(s) fi
The syntax is as follows:
case $variable in model1) function ... ;; model2) function ... ;; model3 | model4 | model5 ) function ... ;; esac
The syntax is as follows:
for variable in variable_list do command(s) done
The syntax is as follows:
while condition do command(s) done
U=1 while [ $U -lt $MAX_ACCOUNTS ] do useradd fenestros"$U" -c fenestros"$U" -d /home/fenestros"$U" -g staff -G audio,fuse -s /bin/bash 2>/dev/null useradd fenestros"$U"$ -g machines -s /dev/false -d /dev/null 2>/dev/null echo "Compte fenestros$U créé" let U=U+1 done
When Bash is called as a login shell it executes the start-up scripts in the following order:
In the case of RHEL/CentOS, Bash executes ~/.bash_profile. In the cas of Debian, Ubuntu and SLES, Bash executes ~/.profile.
When a login shell is terminated, Bash executes the ~/.bash_logout file if it exists.
Whan Bash is called as an interactive shell as opposed to a login shell, it executes only the ~/.bashrc file.
To do : Using the knowledge you have acquired in this unit, explain each of the following scripts.
trainee@debian8:~/training$ cat ~/.profile # ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists. # see /usr/share/doc/bash/examples/startup-files for examples. # the files are located in the bash-doc package. # the default umask is set in /etc/profile; for setting the umask # for ssh logins, install and configure the libpam-umask package. #umask 022 # if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi # set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
trainee@ubuntu1604:~/training$ cat ~/.profile # ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists. # see /usr/share/doc/bash/examples/startup-files for examples. # the files are located in the bash-doc package. # the default umask is set in /etc/profile; for setting the umask # for ssh logins, install and configure the libpam-umask package. #umask 022 # if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi # set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
[trainee@centos7 training]$ cat ~/.bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/.local/bin:$HOME/bin export PATH
trainee@SLES12SP1:~/training> cat ~/.profile # Sample .profile for SuSE Linux # rewritten by Christian Steinruecken <cstein@suse.de> # # This file is read each time a login shell is started. # All other interactive shells will only read .bashrc; this is particularly # important for language settings, see below. test -z "$PROFILEREAD" && . /etc/profile || true # Most applications support several languages for their output. # To make use of this feature, simply uncomment one of the lines below or # add your own one (see /usr/share/locale/locale.alias for more codes) # This overwrites the system default set in /etc/sysconfig/language # in the variable RC_LANG. # #export LANG=de_DE.UTF-8 # uncomment this line for German output #export LANG=fr_FR.UTF-8 # uncomment this line for French output #export LANG=es_ES.UTF-8 # uncomment this line for Spanish output # Some people don't like fortune. If you uncomment the following lines, # you will have a fortune each time you log in ;-) #if [ -x /usr/bin/fortune ] ; then # echo # /usr/bin/fortune # echo #fi
trainee@debian8:~/training$ cat ~/.bashrc # ~/.bashrc: executed by bash(1) for non-login shells. # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) # for examples # If not running interactively, don't do anything case $- in *i*) ;; *) return;; esac # don't put duplicate lines or lines starting with space in the history. # See bash(1) for more options HISTCONTROL=ignoreboth # append to the history file, don't overwrite it shopt -s histappend # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000 HISTFILESIZE=2000 # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # If set, the pattern "**" used in a pathname expansion context will # match all files and zero or more directories and subdirectories. #shopt -s globstar # make less more friendly for non-text input files, see lesspipe(1) #[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" # set variable identifying the chroot you work in (used in the prompt below) if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi # set a fancy prompt (non-color, unless we know we "want" color) case "$TERM" in xterm-color) color_prompt=yes;; esac # uncomment for a colored prompt, if the terminal has the capability; turned # off by default to not distract the user: the focus in a terminal window # should be on the output of commands, not on the prompt #force_color_prompt=yes if [ -n "$force_color_prompt" ]; then if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then # We have color support; assume it's compliant with Ecma-48 # (ISO/IEC-6429). (Lack of such support is extremely rare, and such # a case would tend to support setf rather than setaf.) color_prompt=yes else color_prompt= fi fi if [ "$color_prompt" = yes ]; then PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' else PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' fi unset color_prompt force_color_prompt # If this is an xterm set the title to user@host:dir case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" ;; *) ;; esac # enable color support of ls and also add handy aliases if [ -x /usr/bin/dircolors ]; then test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" alias ls='ls --color=auto' #alias dir='dir --color=auto' #alias vdir='vdir --color=auto' #alias grep='grep --color=auto' #alias fgrep='fgrep --color=auto' #alias egrep='egrep --color=auto' fi # colored GCC warnings and errors #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' # some more ls aliases #alias ll='ls -l' #alias la='ls -A' #alias l='ls -CF' # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi
trainee@ubuntu1604:~/training$ cat ~/.bashrc # ~/.bashrc: executed by bash(1) for non-login shells. # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) # for examples # If not running interactively, don't do anything case $- in *i*) ;; *) return;; esac # don't put duplicate lines or lines starting with space in the history. # See bash(1) for more options HISTCONTROL=ignoreboth # append to the history file, don't overwrite it shopt -s histappend # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000 HISTFILESIZE=2000 # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # If set, the pattern "**" used in a pathname expansion context will # match all files and zero or more directories and subdirectories. #shopt -s globstar # make less more friendly for non-text input files, see lesspipe(1) [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" # set variable identifying the chroot you work in (used in the prompt below) if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi # set a fancy prompt (non-color, unless we know we "want" color) case "$TERM" in xterm-color|*-256color) color_prompt=yes;; esac # uncomment for a colored prompt, if the terminal has the capability; turned # off by default to not distract the user: the focus in a terminal window # should be on the output of commands, not on the prompt #force_color_prompt=yes if [ -n "$force_color_prompt" ]; then if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then # We have color support; assume it's compliant with Ecma-48 # (ISO/IEC-6429). (Lack of such support is extremely rare, and such # a case would tend to support setf rather than setaf.) color_prompt=yes else color_prompt= fi fi if [ "$color_prompt" = yes ]; then PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' else PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' fi unset color_prompt force_color_prompt # If this is an xterm set the title to user@host:dir case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" ;; *) ;; esac # enable color support of ls and also add handy aliases if [ -x /usr/bin/dircolors ]; then test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" alias ls='ls --color=auto' #alias dir='dir --color=auto' #alias vdir='vdir --color=auto' alias grep='grep --color=auto' alias fgrep='fgrep --color=auto' alias egrep='egrep --color=auto' fi # colored GCC warnings and errors #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' # some more ls aliases alias ll='ls -alF' alias la='ls -A' alias l='ls -CF' # Add an "alert" alias for long running commands. Use like so: # sleep 10; alert alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi
[trainee@centos7 training]$ cat ~/.bashrc # .bashrc # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi # Uncomment the following line if you don't like systemctl's auto-paging feature: # export SYSTEMD_PAGER= # User specific aliases and functions
trainee@SLES12SP1:~/training> cat ~/.bashrc # Sample .bashrc for SuSE Linux # Copyright (c) SuSE GmbH Nuernberg # There are 3 different types of shells in bash: the login shell, normal shell # and interactive shell. Login shells read ~/.profile and interactive shells # read ~/.bashrc; in our setup, /etc/profile sources ~/.bashrc - thus all # settings made here will also take effect in a login shell. # # NOTE: It is recommended to make language settings in ~/.profile rather than # here, since multilingual X sessions would not work properly if LANG is over- # ridden in every subshell. # Some applications read the EDITOR variable to determine your favourite text # editor. So uncomment the line below and enter the editor of your choice :-) #export EDITOR=/usr/bin/vim #export EDITOR=/usr/bin/mcedit # For some news readers it makes sense to specify the NEWSSERVER variable here #export NEWSSERVER=your.news.server # If you want to use a Palm device with Linux, uncomment the two lines below. # For some (older) Palm Pilots, you might need to set a lower baud rate # e.g. 57600 or 38400; lowest is 9600 (very slow!) # #export PILOTPORT=/dev/pilot #export PILOTRATE=115200 test -s ~/.alias && . ~/.alias || true
<html>
Copyright © 2004-2017 Hugh Norris.<br><br> <a rel=“license” href=“http://creativecommons.org/licenses/by-nc-nd/3.0/fr/”><img alt=“Licence Creative Commons” style=“border-width:0” src=“http://i.creativecommons.org/l/by-nc-nd/3.0/fr/88x31.png” /></a><br />Ce(tte) oeuvre est mise à disposition selon les termes de la <a rel=“license” href=“http://creativecommons.org/licenses/by-nc-nd/3.0/fr/”>Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 3.0 France</a>.
</html>