Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
elearning:workbooks:redhat:rh124en:l104 [2024/11/11 12:45] – removed admin | elearning:workbooks:redhat:rh124en:l104 [2024/11/26 10:56] (Version actuelle) – admin | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ~~PDF: | ||
+ | Version : **2024.01** | ||
+ | |||
+ | Last update : ~~LASTMOD~~ | ||
+ | |||
+ | ====== RH12405 - The Command Line Interface====== | ||
+ | |||
+ | =====Contents===== | ||
+ | |||
+ | * **RH12405 - The Command Line Interface** | ||
+ | * Contents | ||
+ | * The Shell | ||
+ | * LAB #1 - The /bin/bash Shell | ||
+ | * 1.1 - Shell Internal and External Commands | ||
+ | * 1.2 - Aliases | ||
+ | * 1.3 - Defining a user's shell | ||
+ | * 1.4 - The Prompt | ||
+ | * 1.5 - Recalling commands | ||
+ | * 1.6 - Generating file name endings | ||
+ | * 1.7 - The interactive shell | ||
+ | * Character * | ||
+ | * Character ? | ||
+ | * Character [ ] | ||
+ | * 1.8 - The extglob option | ||
+ | * ? | ||
+ | * *(expression) | ||
+ | * +(expression) | ||
+ | * @(expression) | ||
+ | * !(expression) | ||
+ | * Protecting Metacharacters | ||
+ | * 1.9 - Exit Codes | ||
+ | * 1.10 - Redirections | ||
+ | * 1.11 - Pipes | ||
+ | * 1.12 - Command substitution | ||
+ | * 1.13 - Command chaining | ||
+ | * 1.14 - Displaying shell variables | ||
+ | * Main variables | ||
+ | * Internationalization and Localization Variables | ||
+ | * Special variables | ||
+ | * 1.15 - The env command | ||
+ | * 1.16 - Bash Shell options | ||
+ | * Examples | ||
+ | * noclobber | ||
+ | * noglob | ||
+ | * nounset | ||
+ | |||
+ | =====The Shell===== | ||
+ | |||
+ | A shell is a **command line interpreter** (C.L.I). It is used as an interface to give instructions or **commands** to the operating system. | ||
+ | |||
+ | The word shell is generic. There are many shells in the Unix world, for example : | ||
+ | |||
+ | ^ 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, | ||
+ | |||
+ | Under RHEL 9 the **/bin/sh** shell is a symbolic link to **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ ls -l /bin/sh | ||
+ | lrwxrwxrwx. 1 root root 4 Feb 15 2024 /bin/sh -> bash | ||
+ | </ | ||
+ | |||
+ | =====LAB #1 - The /bin/bash Shell===== | ||
+ | |||
+ | This module is about using the **bash** shell under Linux. The **bash** shell allows you to: | ||
+ | |||
+ | * Recall previously typed commands | ||
+ | * Auto-generate the end of a file name | ||
+ | * Use Aliases | ||
+ | * Use tables | ||
+ | * Use C language numerical and math variables | ||
+ | * Manage strings | ||
+ | * Use Functions | ||
+ | |||
+ | A command always begins with a keyword. This keyword is interpreted by the shell according to the type of command and in the following order: | ||
+ | |||
+ | * An Alias, | ||
+ | * A Function, | ||
+ | * A Built-in Command, | ||
+ | * An External Command. | ||
+ | |||
+ | ====1.1 - Built-in and External Shell Commands==== | ||
+ | |||
+ | Built-in shell commands are commands such as **cd**. To check the type of command, use the **type** command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ type cd | ||
+ | cd is a shell builtin | ||
+ | </ | ||
+ | |||
+ | Commands external to the shell are executable binaries or scripts, generally located in /bin, /sbin, /usr/bin or /usr/sbin : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ type ifconfig | ||
+ | ifconfig is / | ||
+ | </ | ||
+ | |||
+ | ====1.2 - Aliases==== | ||
+ | |||
+ | Aliases are names used to designate a command or a sequence of commands and are specific only to the shell that created them and to the user's environment : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ type ls | ||
+ | ls is aliased to `ls --color=auto' | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | An alias is defined using the **alias** command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ alias dir=‘ls -l’ | ||
+ | [trainee@redhat9 ~]$ dir | ||
+ | total 4 | ||
+ | -rw-r--r--. 1 trainee trainee 0 Sep 25 15:11 aac | ||
+ | -rw-r--r--. 1 trainee trainee 0 Sep 25 15:11 abc | ||
+ | -rw-r--r--. 1 trainee trainee 0 Sep 25 15:11 bca | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Desktop | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Documents | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Downloads | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Music | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Pictures | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Public | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Templates | ||
+ | drwxr-xr-x. 2 trainee trainee 6 Oct 19 2023 Videos | ||
+ | -rw-r--r--. 1 trainee trainee 442 Sep 25 14:24 vitext | ||
+ | -rw-r--r--. 1 trainee trainee 0 Sep 25 15:11 xyz | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | The list of defined aliases can be viewed using the **alias** command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ 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 xzegrep=‘xzegrep --color=auto’ | ||
+ | alias xzfgrep=‘xzfgrep --color=auto’ | ||
+ | alias xzgrep=‘xzgrep --color=auto’ | ||
+ | alias zegrep=‘zegrep --color=auto’ | ||
+ | alias zfgrep=‘zfgrep --color=auto’ | ||
+ | alias zgrep=‘zgrep --color=auto’ | ||
+ | </ | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | To force execution of a command and not the alias you must precede the command with the **\** character: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ \dir | ||
+ | aac abc bca Desktop Documents Downloads Music Pictures Public Templates Videos vitext xyz | ||
+ | </ | ||
+ | |||
+ | To delete an alias, use the **unalias** command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ unalias dir | ||
+ | [trainee@redhat9 ~]$ dir | ||
+ | aac abc bca Desktop Documents Downloads Music Pictures Public Templates Videos vitext xyz | ||
+ | </ | ||
+ | |||
+ | ====1.3 - Defining a user's shell==== | ||
+ | |||
+ | The user shell is defined by **root** in the last field of the **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ cat /etc/passwd | ||
+ | root: | ||
+ | bin: | ||
+ | daemon: | ||
+ | adm: | ||
+ | lp: | ||
+ | sync: | ||
+ | shutdown: | ||
+ | halt: | ||
+ | mail: | ||
+ | operator: | ||
+ | games: | ||
+ | ftp: | ||
+ | nobody: | ||
+ | systemd-coredump: | ||
+ | dbus: | ||
+ | polkitd: | ||
+ | avahi: | ||
+ | tss: | ||
+ | colord: | ||
+ | clevis: | ||
+ | rtkit: | ||
+ | sssd: | ||
+ | geoclue: | ||
+ | libstoragemgmt: | ||
+ | systemd-oom: | ||
+ | setroubleshoot: | ||
+ | pipewire: | ||
+ | flatpak: | ||
+ | gdm: | ||
+ | cockpit-ws: | ||
+ | cockpit-wsinstance: | ||
+ | gnome-initial-setup: | ||
+ | sshd: | ||
+ | chrony: | ||
+ | dnsmasq: | ||
+ | tcpdump: | ||
+ | trainee: | ||
+ | </ | ||
+ | |||
+ | However the user can change their shell using the **chsh** command. The shells available to system users are listed in the **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ cat /etc/shells | ||
+ | /bin/sh | ||
+ | /bin/bash | ||
+ | /usr/bin/sh | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Then use the **echo** command to display the current **trainee** shell: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ echo $SHELL | ||
+ | /bin/bash | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | Then change the **trainee** shell using the **chsh** command, specifying the value of **/bin/sh** for the new shell: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ chsh | ||
+ | Changing shell for trainee. | ||
+ | New shell [/ | ||
+ | Password: trainee | ||
+ | Shell changed. | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | Next, check the active shell for **trainee** : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ echo $SHELL | ||
+ | /bin/bash | ||
+ | </ | ||
+ | |||
+ | Lastly check the shell stipulated in the **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ cat /etc/passwd | grep trainee | ||
+ | trainee: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | Change your shell to **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ chsh | ||
+ | Changing shell for trainee. | ||
+ | New shell [/bin/sh]: /bin/bash | ||
+ | Password: trainee | ||
+ | Shell changed. | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====1.4 - The Prompt==== | ||
+ | |||
+ | A user's prompt depends on their status: | ||
+ | |||
+ | * **$** for a normal user, | ||
+ | * **#** for root. | ||
+ | |||
+ | ====1.5 - Recalling commands ==== | ||
+ | |||
+ | The **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ history | more | ||
+ | 1 su - | ||
+ | 2 exit | ||
+ | 3 su - | ||
+ | 4 clear | ||
+ | 5 cd / | ||
+ | 6 ls -l | ||
+ | 7 cd afs | ||
+ | 8 ls | ||
+ | 9 cd / | ||
+ | 10 su - | ||
+ | 11 cd ~ | ||
+ | 12 vi vitext | ||
+ | 13 view vitext | ||
+ | 14 vi vitext | ||
+ | 15 vi .exrc | ||
+ | 16 vi vitext | ||
+ | 17 su - | ||
+ | 18 stty -a | ||
+ | 19 date | ||
+ | 20 who | ||
+ | 21 df | ||
+ | 22 df -h | ||
+ | 23 free | ||
+ | 24 free -h | ||
+ | 25 whoami | ||
+ | 26 su - | ||
+ | 27 pwd | ||
+ | 28 cd /tmp | ||
+ | 29 pwd | ||
+ | 30 ls | ||
+ | 31 su - | ||
+ | 32 touch test | ||
+ | 33 ls | ||
+ | 34 echo fenestros | ||
+ | 35 cp test ~ | ||
+ | 36 ls -l ~ | ||
+ | 37 file ~/test | ||
+ | --More-- | ||
+ | [q] | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | The command history is in **emacs** mode by default. As a result, the last command is recalled using the **[Up Arrow]** key or the **[CTRL]-[P]** keys and the next command is recalled using the **[Down Arrow]** key or the **[CTRL]-[N]** keys : | ||
+ | |||
+ | ^ Control Character | ||
+ | | [CTRL]-[P] (= Up Arrow) | ||
+ | | [CTRL]-[N] (= Down Arrow) | ||
+ | |||
+ | To move through the history line : | ||
+ | |||
+ | ^ Control Character | ||
+ | | [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 | | ||
+ | |||
+ | To search the history, use the keys : | ||
+ | |||
+ | ^ Control Character | ||
+ | | [CTRL]-[R] // | ||
+ | | [CTRL]-[S] // | ||
+ | | [CTRL]-[G] | Quit the search mode | | ||
+ | |||
+ | It is also possible to recall the last command in the history using the **!!** characters: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ ls | ||
+ | aac abc bca Desktop Documents Downloads Music Pictures Public Templates Videos vitext xyz | ||
+ | |||
+ | [trainee@redhat9 ~]$ !! | ||
+ | ls | ||
+ | aac abc bca Desktop Documents Downloads Music Pictures Public Templates Videos vitext xyz | ||
+ | </ | ||
+ | |||
+ | You can recall a specific command from the history by using the **!** character followed by the number of the command to be recalled: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ history | ||
+ | 1 su - | ||
+ | 2 exit | ||
+ | 3 su - | ||
+ | 4 clear | ||
+ | 5 cd / | ||
+ | 6 ls -l | ||
+ | 7 cd afs | ||
+ | 8 ls | ||
+ | 9 cd / | ||
+ | 10 su - | ||
+ | ... | ||
+ | 85 echo $SHELL | ||
+ | 86 cat /etc/passwd | grep trainee | ||
+ | 87 chsh | ||
+ | 88 history | more | ||
+ | 89 clear | ||
+ | 90 ls | ||
+ | 91 history | ||
+ | |||
+ | [trainee@redhat9 ~]$ !90 | ||
+ | ls | ||
+ | aac abc bca Desktop Documents Downloads Music Pictures Public Templates Videos vitext xyz | ||
+ | </ | ||
+ | |||
+ | The command callback function is set up for all users in the **/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ cat / | ||
+ | HISTSIZE=1000 | ||
+ | export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL | ||
+ | </ | ||
+ | |||
+ | You will notice that in the previous case, the value of **HISTSIZE** is **1000**. This implies that the last thousand commands are memorised. | ||
+ | |||
+ | The memorised commands are stored in the **~/ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ nl .bash_history | tail | ||
+ | 59 ls | ||
+ | 60 ls | sort | ||
+ | 61 ls | sort -r | ||
+ | 62 more / | ||
+ | 63 less / | ||
+ | 64 find acc | ||
+ | 65 find aac | ||
+ | 66 su - | ||
+ | 67 sleep 10 | ||
+ | 68 su - | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====1.6 - Generating file name endings==== | ||
+ | |||
+ | The /bin/bash shell is used to generate file name endings. This is accomplished by using the **[Tab]** key. In the following example, the command entered is : | ||
+ | |||
+ | $ ls .b [Tab][Tab][Tab] | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ ls .bash | ||
+ | .bash_history .bash_logout .bash_profile .bashrc | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | The same possibility exists for generating command name endings. In this case enter the following command: | ||
+ | |||
+ | $ mo [Tab][Tab] | ||
+ | |||
+ | Press the < | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ mo | ||
+ | modinfo | ||
+ | modprobe | ||
+ | </ | ||
+ | |||
+ | ====1.7 - The interactive shell ==== | ||
+ | |||
+ | When using the shell, we often need to execute a command on several files instead of processing them individually. For this purpose we can use 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 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 ... | | ||
+ | |||
+ | ===The * Metacharacter=== | ||
+ | |||
+ | In your home directory, create a **training** directory. Then create 5 files in this directory named f1, f2, f3, f4 and f5 respectively: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ mkdir training | ||
+ | [trainee@redhat9 ~]$ cd training | ||
+ | [trainee@redhat9 training]$ touch f1 f2 f3 f4 f5 | ||
+ | [trainee@redhat9 training]$ ls | ||
+ | f1 f2 f3 f4 f5 | ||
+ | </ | ||
+ | |||
+ | To demonstrate the use of the metacharacter *, enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo f* | ||
+ | f1 f2 f3 f4 f5 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ===The ? Metacharacter=== | ||
+ | |||
+ | Now create the f52 and f62 files: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ touch f52 f62 | ||
+ | </ | ||
+ | |||
+ | Then enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo f?2 | ||
+ | f52 f62 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ===The [] Metacharacter=== | ||
+ | |||
+ | Usage can take several different forms: | ||
+ | |||
+ | ^ Metacharacter ^ Description ^ | ||
+ | | [xyz] | Represents either x or y or z | | ||
+ | | [m-t] | Represents a character in the range m to 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 characters **[** and **]**, create the file a100 : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ touch a100 | ||
+ | </ | ||
+ | |||
+ | Then enter the following commands and note the result: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo [a-f]* | ||
+ | a100 f1 f2 f3 f4 f5 f52 f62 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo [af]* | ||
+ | a100 f1 f2 f3 f4 f5 f52 f62 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo [!a]* | ||
+ | f1 f2 f3 f4 f5 f52 f62 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo [a-b]* | ||
+ | a100 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo [a-f] | ||
+ | [a-f] | ||
+ | </ | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====1.8 - The extglob option==== | ||
+ | |||
+ | Enable the **extglob** option in the bash shell so that you can use **? | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ shopt -s extglob | ||
+ | </ | ||
+ | |||
+ | The **shopt** command is used to enable or disable options for optional shell behaviour. The list of options can be viewed by executing the **shopt** command without options: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ shopt | ||
+ | autocd off | ||
+ | assoc_expand_once off | ||
+ | cdable_vars off | ||
+ | cdspell off | ||
+ | checkhash off | ||
+ | checkjobs off | ||
+ | checkwinsize on | ||
+ | cmdhist on | ||
+ | compat31 off | ||
+ | compat32 off | ||
+ | compat40 off | ||
+ | compat41 off | ||
+ | compat42 off | ||
+ | compat43 off | ||
+ | compat44 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 | ||
+ | globasciiranges on | ||
+ | globstar off | ||
+ | gnu_errfmt off | ||
+ | histappend on | ||
+ | histreedit off | ||
+ | histverify off | ||
+ | hostcomplete off | ||
+ | huponexit off | ||
+ | inherit_errexit off | ||
+ | interactive_comments on | ||
+ | lastpipe off | ||
+ | lithist off | ||
+ | localvar_inherit off | ||
+ | localvar_unset off | ||
+ | login_shell on | ||
+ | mailwarn off | ||
+ | no_empty_cmd_completion off | ||
+ | nocaseglob off | ||
+ | nocasematch off | ||
+ | nullglob off | ||
+ | progcomp on | ||
+ | progcomp_alias off | ||
+ | promptvars on | ||
+ | restricted_shell off | ||
+ | shift_verbose off | ||
+ | sourcepath on | ||
+ | syslog_history off | ||
+ | xpg_echo off | ||
+ | </ | ||
+ | |||
+ | ===? | ||
+ | |||
+ | Create the files f, f.txt, f123.txt, f123123.txt, | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ touch f f.txt f123.txt f123123.txt f123123123.txt | ||
+ | </ | ||
+ | |||
+ | Enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ ls f?(123).txt | ||
+ | f123.txt f.txt | ||
+ | </ | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ===*(expression)=== | ||
+ | |||
+ | Enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ ls f*(123).txt | ||
+ | f123123123.txt f123123.txt f123123.txt f.txt | ||
+ | </ | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ===+(expression)=== | ||
+ | |||
+ | Enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ ls f+(123).txt | ||
+ | f123123123.txt f123123.txt f123.txt | ||
+ | </ | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important** : Note here that the command displays files with names containing between 1 and x occurrences of the string **123**. | ||
+ | </ | ||
+ | |||
+ | ===@(expression)=== | ||
+ | |||
+ | Enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ ls f@(123).txt | ||
+ | f123.txt | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ===!(expression)=== | ||
+ | |||
+ | Enter the following command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ ls f!(123).txt | ||
+ | f123123123.txt f123123.txt f.txt | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====Protecting Metacharacters==== | ||
+ | |||
+ | In order to use a metacharacter in a literal context, an escape character must be used. There are three escape characters: | ||
+ | |||
+ | ^ Character ^ Description ^ | ||
+ | | \ | Escapes the character which immediately follows | | ||
+ | | ' ' | Protects any character between the two **'** | | ||
+ | | " " | Protects any character between the two **"** except the following: **$**, **\** and **'** | | ||
+ | |||
+ | To illustrate the use of escape characters, consider the following command: | ||
+ | |||
+ | echo * is a metacharacter [Enter]. | ||
+ | |||
+ | When you enter this command in your **training** directory, you will get a window similar to this one: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ echo * is a metacharacter | ||
+ | a100 f f1 f123123123.txt f123123.txt f123123.txt f2 f3 f4 f5 f52 f62 f.txt is a metacharacter | ||
+ | |||
+ | [trainee@redhat9 training]$ echo \* is a metacharacter | ||
+ | * is a metacharacter | ||
+ | |||
+ | [trainee@redhat9 training]$ echo "* is a metacharacter" | ||
+ | * is a metacharacter | ||
+ | |||
+ | [trainee@redhat9 training]$ echo ‘* is a metacharacter’ | ||
+ | * is a metacharacter | ||
+ | </ | ||
+ | |||
+ | ====1.9 - Exit codes==== | ||
+ | |||
+ | Each command returns an **exit status** when it is executed. This exit status is stored in a special variable: **$?**. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ cd .. | ||
+ | [trainee@redhat9 ~]$ mkdir codes | ||
+ | [trainee@redhat9 ~]$ echo $? | ||
+ | 0 | ||
+ | [trainee@redhat9 ~]$ touch codes/ | ||
+ | [trainee@redhat9 ~]$ rmdir codes | ||
+ | rmdir: failed to remove ‘codes’: | ||
+ | [trainee@redhat9 ~]$ echo $? | ||
+ | 1 | ||
+ | </ | ||
+ | |||
+ | In this example the **codes** directory was created successfully. The exit code stored in the $? variable is a zero. | ||
+ | |||
+ | Deleting the directory encountered an error because **codes** contained the file **return**. The exit code stored in the $? variable is **one**. | ||
+ | |||
+ | If the exit code is **zero**, the last command was executed without error. | ||
+ | |||
+ | If the exit code is **other than zero**, the last command was completed with an error. | ||
+ | |||
+ | ====1.10 - Redirections==== | ||
+ | |||
+ | Your dialogue with the Linux system uses input and output channels. The keyboard is called the **standard input channel** and the screen is called the **standard output channel**: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | In other words, when you type a command on the keyboard, you see the result of that command on the screen. | ||
+ | |||
+ | Sometimes, however, it is useful to redirect the standard output channel to a file. In this way, the result of a command such as **free** can be stored in a file for future reference: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | This effect is achieved by using a **redirection**: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ pwd | ||
+ | / | ||
+ | [trainee@redhat9 ~]$ cd training | ||
+ | [trainee@redhat9 training]$ free > file | ||
+ | [trainee@redhat9 training]$ cat file | ||
+ | | ||
+ | Mem: | ||
+ | Swap: 5242876 | ||
+ | </ | ||
+ | |||
+ | If the target file does not exist, it is created and its contents will be the result of the free command. | ||
+ | |||
+ | On the other hand if the file already exists, it will be overwritten : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ date > file | ||
+ | [trainee@redhat9 training]$ cat file | ||
+ | Thu Sep 26 12:49:11 PM CEST 2024 | ||
+ | </ | ||
+ | |||
+ | To add additional data to the same target file, a **double redirect** must be used: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ free >> file | ||
+ | [trainee@redhat9 training]$ free >> file | ||
+ | [trainee@redhat9 training]$ cat file | ||
+ | Thu Sep 26 12:49:11 PM CEST 2024 | ||
+ | | ||
+ | Mem: | ||
+ | Swap: 5242876 | ||
+ | </ | ||
+ | |||
+ | This way, the output of the free command will be added to the end of your file after the information in the free command. | ||
+ | |||
+ | <WRAP centre round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | Input and output channels are numbered: | ||
+ | |||
+ | * 0 = The Standard Input Channel | ||
+ | * 1 = The Standard Output Channel | ||
+ | * 2 = The Error Channel | ||
+ | |||
+ | The following command will create a file named **errorlog** that contains error messages from the execution of the **rmdir** command: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 training]$ cd .. | ||
+ | [trainee@redhat9 ~]$ rmdir training/ 2> | ||
+ | [trainee@redhat9 ~]$ cat errorlog | ||
+ | rmdir: failed to remove ‘training/ | ||
+ | </ | ||
+ | |||
+ | In fact the error is generated because the **training** directory is not empty. | ||
+ | |||
+ | You can join file descriptors using the **&** character: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ free > file 2>&1 | ||
+ | </ | ||
+ | |||
+ | The syntax **2>& | ||
+ | |||
+ | It is possible to modify the standard input channel in order to read information from a file. In this case the redirection is obtained by using the **<** character: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ wc -w < errorlog | ||
+ | 8 | ||
+ | </ | ||
+ | |||
+ | In this example the wc command counts the number of words ( -w ) in the errorlog file and displays it on the screen : | ||
+ | |||
+ | Other redirections exist: | ||
+ | |||
+ | ^ Redirection | ||
+ | | %%&> | ||
+ | | %%<< | ||
+ | | %%<> | ||
+ | |||
+ | ====1.11 - Pipes==== | ||
+ | |||
+ | It is also possible to link commands using a **|** pipe. | ||
+ | |||
+ | In this case, the output channel of the command to the left of the pipe is sent to the input channel of the command to the right of the pipe : | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ ls | wc -w | ||
+ | 17 | ||
+ | </ | ||
+ | |||
+ | This command, run in your home directory, takes the output of the **ls** command and asks the **wc** command to count the number of words included in the output of ls: | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | Remember that the standard output can only be redirected in one direction. In order to be able to redirect the standard output to a file **and** view it on screen, we need to use the **tee** command with a pipe: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ date | tee file1 | ||
+ | Thu Sep 26 12:54:36 PM CEST 2024 | ||
+ | [trainee@redhat9 ~]$ cat file1 | ||
+ | Thu Sep 26 12:54:36 PM CEST 2024 | ||
+ | </ | ||
+ | |||
+ | This same technique allows us to create **two files**: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ date | tee file1 > file2 | ||
+ | [trainee@redhat9 ~]$ cat file1 | ||
+ | Thu Sep 26 12:55:11 PM CEST 2024 | ||
+ | [trainee@redhat9 ~]$ cat file2 | ||
+ | Thu Sep 26 12:55:11 PM CEST 2024 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====1.12 - Command substitutions==== | ||
+ | |||
+ | It is sometimes interesting, | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ echo date | ||
+ | date | ||
+ | |||
+ | [trainee@redhat9 ~]$ echo $(date) | ||
+ | Thu Sep 26 12:56:02 PM CEST 2024 | ||
+ | |||
+ | [trainee@redhat9 ~]$ echo `date` | ||
+ | Thu Sep 26 12:56:17 PM CEST 2024 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important**: | ||
+ | </ | ||
+ | |||
+ | ====1.13 - Command chaining==== | ||
+ | |||
+ | It is possible to group commands together using a sub-shell : | ||
+ | |||
+ | $ (ls -l; ps; who) > list [Enter] | ||
+ | |||
+ | This example sends the results of the three commands to the **list** file, processing them in the background. | ||
+ | |||
+ | The commands can also be chained according to the exit code of the previous command. | ||
+ | |||
+ | **&& | ||
+ | |||
+ | **||** is used to ensure the reverse. | ||
+ | |||
+ | The syntax of this command is : | ||
+ | |||
+ | Command1 && Command2 | ||
+ | |||
+ | In this case, Command2 is only executed if Command1 has run without error. | ||
+ | |||
+ | Or : | ||
+ | |||
+ | Command1 || Command2 | ||
+ | |||
+ | In this case, Command2 is executed if Command1 has encountered an error. | ||
+ | |||
+ | ====1.14 - Displaying shell variables==== | ||
+ | |||
+ | A shell variable can be displayed using the command : | ||
+ | |||
+ | $ echo $VARIABLE [Input] | ||
+ | |||
+ | === Main variables === | ||
+ | |||
+ | ^ 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' | ||
+ | | HISTCONTROL | **ignorespace** or **ignoredups** or **ignoreboth** | | ||
+ | | HOME | The user's home directory. | | ||
+ | | HOSTTYPE | Machine type. | | ||
+ | | OSTYPE | The OS type. | | ||
+ | | MAIL | 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. | | ||
+ | |||
+ | === Internationalization and Localization Variables === | ||
+ | |||
+ | **Internationalization**, | ||
+ | |||
+ | * Text processing differences, | ||
+ | * Writing direction, | ||
+ | * Different systems of numerals, | ||
+ | * Telephone numbers, addresses and international postal codes, | ||
+ | * Weights and measures, | ||
+ | * Date/time format, | ||
+ | * Paper sizes, | ||
+ | * Keyboard layout, | ||
+ | * etc ... | ||
+ | |||
+ | The **Localization**, | ||
+ | |||
+ | The complete country code takes the following form: **language-PAYS.character_set**. For example, for the English language the language-PAYS values are : | ||
+ | |||
+ | * en_GB = Great Britain, | ||
+ | * en_US = USA, | ||
+ | * en_AU = Australia, | ||
+ | * en_NZ = New Zealand, | ||
+ | * en_ZA = South Africa, | ||
+ | * en_CA = Canada. | ||
+ | |||
+ | The most important system variables containing regionalisation information are : | ||
+ | |||
+ | ^ Variable ^ Description ^ | ||
+ | | LC_ALL | With a non-zero value, this takes precedence over the value of all other internationalisation variables. | | ||
+ | | LANG | Provides a default value for environment variables whose value is null or undefined. | | ||
+ | | LC_CTYPE | Determines the regional parameters for interpreting the sequence of bytes of text data in characters. | | ||
+ | |||
+ | For example: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ echo $LC_ALL | ||
+ | |||
+ | [trainee@redhat9 ~]$ echo $LC_CTYPE | ||
+ | |||
+ | [trainee@redhat9 ~]$ echo $LANG | ||
+ | en_US.UTF-8 | ||
+ | [trainee@redhat9 ~]$ locale | ||
+ | LANG=en_US.UTF-8 | ||
+ | LC_CTYPE=" | ||
+ | LC_NUMERIC=" | ||
+ | LC_TIME=" | ||
+ | LC_COLLATE=" | ||
+ | LC_MONETARY=" | ||
+ | LC_MESSAGES=" | ||
+ | LC_PAPER=" | ||
+ | LC_NAME=" | ||
+ | LC_ADDRESS=" | ||
+ | LC_TELEPHONE=" | ||
+ | LC_MEASUREMENT=" | ||
+ | LC_IDENTIFICATION=" | ||
+ | LC_ALL= | ||
+ | </ | ||
+ | |||
+ | ===Special variables=== | ||
+ | |||
+ | ^ 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 | | ||
+ | |||
+ | ====1.15 - The env command ==== | ||
+ | |||
+ | The **env** command sends the values of the system variables in the environment of the user invoking it to the standard output: | ||
+ | |||
+ | < | ||
+ | [trainee@redhat9 ~]$ env | ||
+ | SHELL=/ | ||
+ | HISTCONTROL=ignoredups | ||
+ | HISTSIZE=1000 | ||
+ | HOSTNAME=redhat9.ittraining.loc | ||
+ | PWD=/ | ||
+ | LOGNAME=trainee | ||
+ | XDG_SESSION_TYPE=tty | ||
+ | MOTD_SHOWN=pam | ||
+ | HOME=/ | ||
+ | LANG=en_US.UTF-8 | ||
+ | LS_COLORS=rs=0: |