Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
elearning:workbooks:debian:10:utilisateur:l103 [2022/05/17 07:58] – created admin | elearning:workbooks:debian:10:utilisateur:l103 [2024/03/11 09:31] (Version actuelle) – admin | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
~~PDF: | ~~PDF: | ||
- | Version : **2022.01** | + | Version : **2024.01** |
Dernière mise-à-jour : ~~LASTMOD~~ | Dernière mise-à-jour : ~~LASTMOD~~ | ||
- | ======LCF403 | + | ======LDF403 |
=====Contenu du Module===== | =====Contenu du Module===== | ||
- | * **LCF403 | + | * **LDF403 |
* Contenu du Module | * Contenu du Module | ||
* LAB #1 - Aide des Commandes | * LAB #1 - Aide des Commandes | ||
Ligne 26: | Ligne 26: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ type ip |
- | ifconfig | + | ip is /usr/bin/ip |
</ | </ | ||
Ligne 33: | Ligne 33: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ ip --help |
- | Usage: | + | Usage: |
- | ifconfig | + | |
- | | + | where OBJECT := { link | address |
- | | + | |
- | [[-]broadcast | + | netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila | |
- | [netmask < | + | vrf | sr | nexthop | mptcp } |
- | [outfill <NN>] [keepalive <NN>] | + | |
- | [hw <HW> < | + | -h[uman-readable] | -iec | -j[son] | -p[retty] | |
- | [[-]trailers] | + | -f[amily] { inet | inet6 | mpls | bridge | link } | |
- | | + | -4 | -6 | -I | -D | -M | -B | -0 | |
- | [mem_start <NN>] [io_addr <NN>] [irq <NN>] [media < | + | -l[oops] { maximum-addr-flush-attempts } | -br[ief] | |
- | | + | -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] | |
- | [[-]dynamic] | + | -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] | |
- | | + | -c[olor]} |
- | + | ||
- | < | + | |
- | List of possible hardware types: | + | |
- | loop (Local Loopback) slip (Serial Line IP) cslip (VJ Serial Line IP) | + | |
- | slip6 (6-bit Serial Line IP) cslip6 (VJ 6-bit Serial Line IP) adaptive (Adaptive Serial Line IP) | + | |
- | ash (Ash) ether (Ethernet) ax25 (AMPR AX.25) | + | |
- | netrom (AMPR NET/ROM) rose (AMPR ROSE) tunnel (IPIP Tunnel) | + | |
- | ppp (Point-to-Point Protocol) hdlc ((Cisco)-HDLC) lapb (LAPB) | + | |
- | arcnet (ARCnet) dlci (Frame Relay DLCI) frad (Frame Relay Access Device) | + | |
- | sit (IPv6-in-IPv4) fddi (Fiber Distributed Data Interface) hippi (HIPPI) | + | |
- | irda (IrLAP) x25 (generic X.25) infiniband (InfiniBand) | + | |
- | eui64 (Generic EUI-64) | + | |
- | < | + | |
- | List of possible address families: | + | |
- | unix (UNIX Domain) inet (DARPA Internet) inet6 (IPv6) | + | |
- | ax25 (AMPR AX.25) netrom (AMPR NET/ROM) rose (AMPR ROSE) | + | |
- | ipx (Novell IPX) ddp (Appletalk DDP) ash (Ash) | + | |
- | x25 (CCITT X.25) | + | |
</ | </ | ||
Ligne 73: | Ligne 55: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ type type |
type is a shell builtin | type is a shell builtin | ||
</ | </ | ||
Ligne 80: | Ligne 62: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ help |
- | GNU bash, version | + | GNU bash, version |
These shell commands are defined internally. | These shell commands are defined internally. | ||
Type `help name' to find out more about the function `name' | Type `help name' to find out more about the function `name' | ||
Ligne 89: | Ligne 71: | ||
A star (*) next to a name means that the command is disabled. | A star (*) next to a name means that the command is disabled. | ||
- | | + | |
- | (( expression )) | + | (( expression )) |
- | . filename [arguments] | + | . filename [arguments] |
- | : | + | : |
- | [ arg... ] | + | [ arg... ] |
- | [[ expression ]] | + | [[ expression ]] |
- | alias [-p] [name[=value] ... ] | + | alias [-p] [name[=value] ... ] |
- | bg [job_spec ...] mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] | + | bg [job_spec ...] mapfile [-d delim] [-n count] [-O origi> |
- | bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq: | + | bind [-lpsvPSVX] [-m keymap] [-f filenam> popd [-n] [+N | -N] |
- | break [n] printf [-v var] format [arguments] | + | break [n] printf [-v var] format [arguments] |
- | | + | |
- | | + | |
- | case WORD in [PATTERN [| PATTERN]...) | + | case WORD in [PATTERN [| PATTERN]...) |
- | cd [-L|[-P [-e]] [-@]] [dir] | + | cd [-L|[-P [-e]] [-@]] [dir] |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | dirs [-clpv] [+N] [-N] | + | dirs [-clpv] [+N] [-N] |
- | | + | |
- | echo [-neE] [arg ...] time [-p] pipeline | + | echo [-neE] [arg ...] time [-p] pipeline |
- | | + | |
- | eval [arg ...] | + | eval [arg ...] |
- | exec [-cl] [-a name] [command [arguments ...]] [redirection ...] true | + | exec [-cl] [-a name] [command [argument > |
- | exit [n] | + | exit [n] |
- | | + | |
- | | + | |
- | fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command] | + | fc [-e ename] [-lnr] [first] [last] or f> |
- | fg [job_spec] | + | fg [job_spec] |
- | for NAME [in WORDS ... ] ; do COMMANDS; | + | for NAME [in WORDS ... ] ; do COMMANDS; |
- | for (( exp1; exp2; exp3 )); do COMMANDS; | + | for (( exp1; exp2; exp3 )); do COMMANDS;> |
- | | + | |
- | | + | |
- | hash [-lr] [-p pathname] [-dt] [name ...] | + | hash [-lr] [-p pathname] [-dt] [name ...> |
- | help [-dms] [pattern ...] { COMMANDS ; } | + | help [-dms] [pattern ...] { COMMANDS ; } |
</ | </ | ||
Ligne 132: | Ligne 114: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ help type |
type: type [-afptP] name [name ...] | type: type [-afptP] name [name ...] | ||
Display information about command type. | Display information about command type. | ||
Ligne 166: | Ligne 148: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ man passwd |
- | BASH_BUILTINS(1) General | + | PASSWD(1) User Commands |
NAME | NAME | ||
- | bash, :, ., [, alias, bg, bind, break, builtin, caller, cd, command, compgen, complete, compopt, continue, declare, dirs, disown, echo, enable, eval, exec, exit, export, false, fc, | + | passwd |
- | fg, getopts, hash, help, history, jobs, kill, let, local, logout, mapfile, popd, printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, | + | |
- | true, type, typeset, ulimit, umask, unalias, unset, wait - bash built-in commands, see bash(1) | + | |
- | BASH BUILTIN COMMANDS | + | SYNOPSIS |
- | Unless otherwise noted, each builtin command documented in this section as accepting | + | passwd [options] [LOGIN] |
- | | + | |
- | | + | |
- | this interpretation. | + | |
- | : | + | |
- | No effect; the command does nothing beyond expanding arguments and performing any specified redirections. | + | |
- | . filename [arguments] | + | DESCRIPTION |
- | source filename [arguments] | + | The passwd command changes passwords for user accounts. A normal user may only change |
- | Read and execute commands from filename in the current shell environment and return | + | changes |
- | | + | |
- | rent directory is searched | + | |
- | supplied, | + | The user is first prompted for their old password, if one is present. This password is then encrypted and compared against |
- | any trap on DEBUG; if it is not, any DEBUG trap string is saved and restored around the call to source, and source unsets | + | |
- | | + | |
- | if no commands are executed), and false if filename is not found or cannot | + | After the password has been entered, password aging information is checked to see if the user is permitted to change the password at this time. If not, passwd refuses to change |
+ | | ||
+ | |||
+ | The user is then prompted twice for a replacement password. The second entry is compared against | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | Care must be taken not to include | ||
+ | |||
+ | Hints for user passwords | ||
+ | The security of a password depends upon the strength of the encryption algorithm and the size of the key space. The legacy UNIX System encryption method | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | You can find advice on how to choose a strong password on http:// | ||
+ | |||
+ | OPTIONS | ||
+ | The options which apply to the passwd command are: | ||
+ | |||
+ | -a, --all | ||
+ | This option can be used only with -S and causes show status for all users. | ||
+ | |||
+ | -d, --delete | ||
+ | | ||
- | alias [-p] [name[=value] ...] | + | -e, --expire |
- | Alias with no arguments or with the -p option prints the list of aliases in the form alias name=value on standard output. | + | Immediately expire |
- | each name whose value is given. A trailing space in value causes | + | |
- | list for which no value is supplied, the name and value of the alias is printed. | + | |
- | bg [jobspec ...] | + | -h, --help |
- | Resume each suspended job jobspec in the background, as if it had been started with & | + | Display help message and exit. |
- | | + | |
- | bind [-m keymap] [-lpsvPSVX] | + | -i, --inactive INACTIVE |
- | bind [-m keymap] [-q function] [-u function] [-r keyseq] | + | This option is used to disable an account after the password has been expired for a number of days. After a user account has had an expired password for INACTIVE days, the user may no longer |
- | bind [-m keymap] -f filename | + | sign on to the account. |
- | bind [-m keymap] -x keyseq: | + | |
- | bind [-m keymap] keyseq: | + | |
- | bind [-m keymap] keyseq: | + | |
- | Display | + | |
- | it would appear in .inputrc, but each binding or command must be passed as a separate argument; e.g., '" | + | |
- | | + | |
</ | </ | ||
Ligne 215: | Ligne 213: | ||
^ Section ^ Contenu ^ | ^ Section ^ Contenu ^ | ||
- | | NOM | Nom et rôle de la commande | | + | | NOM / NAME | Nom et rôle de la commande | |
| SYNOPSIS | Syntaxe de la commande, paramètres et arguments | | | SYNOPSIS | Syntaxe de la commande, paramètres et arguments | | ||
| DESCRIPTION | Mode d' | | DESCRIPTION | Mode d' | ||
Ligne 256: | Ligne 254: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ whereis passwd |
- | passwd: / | + | passwd: / |
</ | </ | ||
Ligne 263: | Ligne 261: | ||
| | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11:~$ man 5 passwd |
- | PASSWD(5) | + | PASSWD(5) |
NAME | NAME | ||
- | | + | |
DESCRIPTION | DESCRIPTION | ||
- | The / | + | / |
- | user IDs to usernames), but write access only for the superuser. | + | |
- | In the good old days there was no great problem with this general read permission. | + | • login name |
- | | + | |
- | an ' | + | |
- | If the encrypted password, whether in /etc/passwd or in / | + | • |
- | | + | |
- | If the encrypted password in /etc/passwd is " | + | • |
- | Regardless | + | • |
- | or herself using a password. | + | |
- | If you create a new login, first put an asterisk (*) in the password | + | • user name or comment |
- | Each line of the file describes a single | + | • user home directory |
- | | + | |
- | The field are as follows: | + | If the password |
+ | | ||
- | name This is the user' | + | The encrypted password field may be empty, in which case no password |
+ | not to permit any access at all if the password field is blank. | ||
- | | + | A password field which starts with an exclamation mark means that the password is locked. The remaining characters on the line represent |
- | UID The privileged root login account | + | Refer to crypt(3) for details on how this string is interpreted. |
- | GID This is the numeric primary group ID for this user. | + | If the password field contains some string that is not a valid result of crypt(3), |
+ | system | ||
- | GECOS This field (sometimes called the "comment field" | + | The comment field is used by various system utilities, such as finger(1). |
- | ple, finger(1)) display information from this field. | + | |
- | | + | The home directory field provides the name of the initial working directory. The login program uses this information |
- | | + | |
+ | The command interpreter field provides the name of the user' | ||
+ | of the $SHELL environmental variable. If this field is empty, it defaults | ||
+ | |||
+ | FILES | ||
+ | / | ||
+ | User account | ||
+ | |||
+ | / | ||
+ | | ||
+ | |||
+ | / | ||
+ | | ||
+ | |||
+ | Note that this file is used by the tools of the shadow toolsuite, but not by all user and password management tools. | ||
+ | |||
+ | SEE ALSO | ||
+ | | ||
+ | |||
+ | shadow-utils 4.8.1 | ||
| | ||
</ | </ | ||
Ligne 318: | Ligne 332: | ||
< | < | ||
- | [root@centos8 | + | trainee@debian11: |
- | Processing manual pages under / | + | Password: fenestros |
- | Updating index cache for path `/ | + | |
- | Checking for stray cats under / | + | root@debian11:~# which mandb |
- | Checking for stray cats under /var/cache/man/overrides... | + | / |
- | ... | + | |
+ | root@debian11: | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in /usr/ | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in /usr/ | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under /usr/share/man/zh_TW... | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
Processing manual pages under / | Processing manual pages under / | ||
- | Purging old database entries in /usr/local/ | + | Purging old database entries in /usr/share/ |
- | Processing manual pages under /usr/local/ | + | Processing manual pages under /usr/share/man/ja... |
+ | Purging old database entries in / | ||
+ | Processing manual pages under /usr/share/ | ||
+ | Purging old database entries in /usr/share/ | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Purging old database entries in / | ||
+ | Processing manual pages under / | ||
+ | Processing manual pages under /usr/local/man... | ||
0 man subdirectories contained newer manual pages. | 0 man subdirectories contained newer manual pages. | ||
0 manual pages were added. | 0 manual pages were added. | ||
0 stray cats were added. | 0 stray cats were added. | ||
- | 17 old database entries were purged. | + | 0 old database entries were purged. |
</ | </ | ||
Ligne 336: | Ligne 401: | ||
< | < | ||
- | [root@centos8 | + | root@debian11:~# whatis passwd |
- | openssl-passwd (1ssl) - compute | + | passwd (1) |
- | passwd (1) | + | passwd (1ssl) - compute password hashes |
- | passwd (5) - password file | + | passwd (5) |
</ | </ | ||
Ligne 347: | Ligne 412: | ||
< | < | ||
- | [root@centos8 | + | root@debian11:~# apropos passwd |
chgpasswd (8) - update group passwords in batch mode | chgpasswd (8) - update group passwords in batch mode | ||
chpasswd (8) - update passwords in batch mode | chpasswd (8) - update passwords in batch mode | ||
- | fgetpwent_r (3) - get passwd file entry reentrantly | ||
- | getpwent_r (3) - get passwd file entry reentrantly | ||
gpasswd (1) - administer /etc/group and / | gpasswd (1) - administer /etc/group and / | ||
- | grub2-mkpasswd-pbkdf2 (1) - Generate a PBKDF2 password hash. | + | grub-mkpasswd-pbkdf2 (1) - generate hashed |
- | lpasswd (1) - Change group or user password | + | |
openssl-passwd (1ssl) - compute password hashes | openssl-passwd (1ssl) - compute password hashes | ||
pam_localuser (8) - require users to be listed in /etc/passwd | pam_localuser (8) - require users to be listed in /etc/passwd | ||
- | passwd (1) | + | passwd (1) |
- | passwd (5) - password file | + | passwd (1ssl) |
- | passwd2des | + | passwd (5) |
- | pwhistory_helper | + | update-passwd |
- | smbpasswd | + | </ |
- | sslpasswd | + | |
+ | < | ||
+ | root@debian11: | ||
+ | chgpasswd | ||
+ | chpasswd (8) - update passwords in batch mode | ||
+ | gpasswd (1) - administer /etc/group and / | ||
+ | grub-mkpasswd-pbkdf2 (1) - generate hashed | ||
+ | openssl-passwd | ||
+ | pam_localuser (8) - require users to be listed in /etc/passwd | ||
+ | passwd | ||
+ | passwd | ||
+ | passwd (5) - the password file | ||
+ | update-passwd (8) - safely update / | ||
</ | </ | ||
Le résultat est une liste de commandes suivies par une description brève de celles-ci. | Le résultat est une liste de commandes suivies par une description brève de celles-ci. | ||
- | <WRAP center round important | + | <WRAP center round important> |
**Important** - Notez que les numéros entre parenthèses indiquent les sections disponibles. | **Important** - Notez que les numéros entre parenthèses indiquent les sections disponibles. | ||
</ | </ | ||
Ligne 391: | Ligne 465: | ||
| q | Quitter le système **info**. | | | q | Quitter le système **info**. | | ||
- | Pour accéder au premier nœud, utilisez la commande | + | La commande |
< | < | ||
- | [root@centos8 | + | root@debian11:~# apt update |
+ | Hit:1 http:// | ||
+ | Get:2 http:// | ||
+ | Get:3 http:// | ||
+ | Get:4 http:// | ||
+ | Get:5 http:// | ||
+ | Get:6 http:// | ||
+ | Fetched 444 kB in 1s (651 kB/s) | ||
+ | Reading package lists... Done | ||
+ | Building dependency tree... Done | ||
+ | Reading state information... Done | ||
+ | 16 packages can be upgraded. Run 'apt list --upgradable' | ||
+ | |||
+ | root@debian11: | ||
... | ... | ||
+ | </ | ||
+ | |||
+ | Pour accéder au premier nœud, utilisez la commande suivante : | ||
+ | |||
+ | < | ||
+ | root@debian11: | ||
File: dir, Node: Top, This is the top of the INFO tree. | File: dir, Node: Top, This is the top of the INFO tree. | ||
Ligne 407: | Ligne 500: | ||
* Menu: | * Menu: | ||
- | |||
- | Archiving | ||
- | * Cpio: (cpio). | ||
- | * Tar: (tar). | ||
Basics | Basics | ||
- | * Bash: (bash). | ||
* Common options: (coreutils)Common options. | * Common options: (coreutils)Common options. | ||
* Coreutils: (coreutils). | * Coreutils: (coreutils). | ||
* Date input formats: (coreutils)Date input formats. | * Date input formats: (coreutils)Date input formats. | ||
- | * Ed: (ed). The GNU line editor | ||
* File permissions: | * File permissions: | ||
Access modes. | Access modes. | ||
* Finding files: (find). | * Finding files: (find). | ||
- | * time: (time). | ||
Compression | Compression | ||
- | -----Info: (dir)Top, | + | * Gzip: (gzip). |
- | Welcome to Info version 6.5. Type H for help, h for tutorial. | + | |
+ | Development | ||
+ | * SSIP: (ssip). | ||
+ | * Speech Dispatcher: (speech-dispatcher). | ||
+ | Speech Dispatcher. | ||
+ | |||
+ | Editors | ||
+ | * nano: (nano). | ||
+ | |||
+ | GNU organization | ||
+ | * Maintaining Findutils: (find-maint). | ||
+ | Maintaining GNU findutils | ||
+ | |||
+ | GNU Utilities | ||
+ | * dirmngr-client: | ||
+ | * dirmngr: (gnupg). | ||
+ | * gpg-agent: (gnupg). | ||
+ | * gpg2: (gnupg). | ||
+ | * gpgsm: (gnupg). | ||
+ | |||
+ | Individual utilities | ||
+ | * arch: (coreutils)arch invocation. | ||
+ | * b2sum: (coreutils)b2sum invocation. | ||
+ | * base32: (coreutils)base32 invocation. | ||
+ | * base64: (coreutils)base64 invocation. | ||
+ | * basename: (coreutils)basename invocation. | ||
+ | * basenc: (coreutils)basenc invocation. | ||
+ | * cat: (coreutils)cat invocation. | ||
+ | * chcon: (coreutils)chcon invocation. | ||
+ | * chgrp: (coreutils)chgrp invocation. | ||
+ | * chmod: (coreutils)chmod invocation. | ||
+ | * chown: (coreutils)chown invocation. | ||
+ | * chroot: (coreutils)chroot invocation. | ||
+ | * cksum: (coreutils)cksum invocation. | ||
+ | * cmp: (diffutils)Invoking cmp. | ||
+ | -----Info: (dir)Top, | ||
+ | Welcome to Info version 6.7. Type H for help, h for tutorial. | ||
</ | </ | ||
+ | |||
+ | Pour accéder au tutoriel concernant l' | ||
+ | |||
+ | < | ||
+ | Next: Stand-alone Info, Up: (dir) | ||
+ | |||
+ | Stand-alone GNU Info | ||
+ | ******************** | ||
+ | |||
+ | This documentation describes the stand-alone Info reader which you can | ||
+ | use to read Info documentation. | ||
+ | |||
+ | If you are new to the Info reader, then you can get started by typing | ||
+ | ' | ||
+ | this manual by typing <SPC> and <DEL> (or < | ||
+ | move forwards and backwards in it. | ||
+ | |||
+ | * Menu: | ||
+ | |||
+ | * Stand-alone Info:: | ||
+ | * Invoking Info:: | ||
+ | * Cursor Commands:: | ||
+ | * Scrolling Commands:: | ||
+ | * Node Commands:: | ||
+ | * Searching Commands:: | ||
+ | * Index Commands:: | ||
+ | * Xref Commands:: | ||
+ | * Window Commands:: | ||
+ | * Printing Nodes:: | ||
+ | * Miscellaneous Commands:: | ||
+ | * Variables:: | ||
+ | * Colors and Styles:: | ||
+ | * Custom Key Bindings:: | ||
+ | * Index:: | ||
+ | </ | ||
+ | |||
+ | Pour quitter, utilisez la touche **q**. | ||
----- | ----- | ||
- | Copyright © 2022 Hugh Norris. | + | Copyright © 2024 Hugh Norris. |