Watael a écritsalut,
Bonjour Maître Jedi Watael... toujours content que tu prennes un peu de temps pour te pencher sur une de mes élucubrations !
Watael a écritles noms des variables doivent ne pas être tout en majuscules.
ça ok... pas de soucis... j'ai repris... j'y reviendrais pour qu'elles soient un peu plus lisibles
Watael a écritles accolades dans le développement de paramètres sont inutiles s'ils ne protègent pas d'une concaténation, ou n'indiquent pas une substitution. c'est pourquoi leur utilisation systématique est "nuisible".
là c'est plus compliqué pour moi... j'ai fait ça moi ? :lol:
alors attends j'essaie déjà de comprendre...
le développement de paramètres dans l'appelle d'une fonction ?
par exemple :
parametre="blabla"
ma_fonction(){
#une fonction qui fait des trucs
echo "je suis une fonction"
}
ma_fonction $parametre
et non pas :
ma_fonction ${parametre}
je pensais plus à l’esthétisme, la facilité de lecture voire la sécurité d'une façon générale...
mais une règle liée à la protection lors de concaténation... et que cela puisse avoir un côté "nuisible"...
... bon je vais y cogiter... je n'y ai pas touché encore...
Watael a écritfor ligne in $(cat fichier) ->while read ligne; do : ...; done <fichier
oui... ouiiii... j'ai quand même dû tatonner un peu et rezieuter des exemples contrairement à la lecture dans le cat que je sort plus intuitivement...
j'arrive à ça :
charger_ext_connues () {
les_ext_connues=()
les_noms_dossiers=()
local une_ligne
while IFS= read -r une_ligne
do
les_ext_connues+=( ${une_ligne%%;*} )
les_noms_dossiers+=( ${une_ligne##*;} )
done < "${file_ext_connues}"
}
mais tripoter à IFS semble masturbatoire !
while read -r une_ligne
do
les_ext_connues+=( ${une_ligne%%;*} )
les_noms_dossiers+=( ${une_ligne##*;} )
done < "${file_ext_connues}"
par contre le -r ne me semble pas facultatif...
... et en parlant de ça, j'ai jamais pigé :
kiki@Sat-L500:~$ man read
kiki@Sat-L500:~$ info read
READ(2) Linux Programmer's Manual READ(2)
NAME
read - read from a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
DESCRIPTION
read() attempts to read up to count bytes from file descriptor fd into
the buffer starting at buf.
On files that support seeking, the read operation commences at the cur‐
rent file offset, and the file offset is incremented by the number of
bytes read. If the current file offset is at or past the end of file,
no bytes are read, and read() returns zero.
If count is zero, read() may detect the errors described below. In the
absence of any errors, or if read() does not check for errors, a read()
with a count of 0 returns zero and has no other effects.
If count is greater than SSIZE_MAX, the result is unspecified.
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of
file), and the file position is advanced by this number. It is not an
error if this number is smaller than the number of bytes requested;
this may happen for example because fewer bytes are actually available
right now (maybe because we were close to end-of-file, or because we
are reading from a pipe, or from a terminal), or because read() was
interrupted by a signal. See also NOTES.
On error, -1 is returned, and errno is set appropriately. In this
case, it is left unspecified whether the file position (if any)
changes.
ERRORS
EAGAIN The file descriptor fd refers to a file other than a socket and
has been marked nonblocking (O_NONBLOCK), and the read would
block. See open(2) for further details on the O_NONBLOCK flag.
EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been marked
nonblocking (O_NONBLOCK), and the read would block.
POSIX.1-2001 allows either error to be returned for this case,
and does not require these constants to have the same value, so
a portable application should check for both possibilities.
EBADF fd is not a valid file descriptor or is not open for reading.
EFAULT buf is outside your accessible address space.
EINTR The call was interrupted by a signal before any data was read;
see signal(7).
EINVAL fd is attached to an object which is unsuitable for reading; or
the file was opened with the O_DIRECT flag, and either the
address specified in buf, the value specified in count, or the
current file offset is not suitably aligned.
EINVAL fd was created via a call to timerfd_create(2) and the wrong
size buffer was given to read(); see timerfd_create(2) for fur‐
ther information.
EIO I/O error. This will happen for example when the process is in
a background process group, tries to read from its controlling
terminal, and either it is ignoring or blocking SIGTTIN or its
process group is orphaned. It may also occur when there is a
low-level I/O error while reading from a disk or tape.
EISDIR fd refers to a directory.
Other errors may occur, depending on the object connected to fd. POSIX
allows a read() that is interrupted after reading some data to return
-1 (with errno set to EINTR) or to return the number of bytes already
read.
CONFORMING TO
SVr4, 4.3BSD, POSIX.1-2001.
NOTES
On Linux, read() (and similar system calls) will transfer at most
0x7ffff000 (2,147,479,552) bytes, returning the number of bytes actu‐
ally transferred. (This is true on both 32-bit and 64-bit systems.)
On NFS filesystems, reading small amounts of data will update the time‐
stamp only the first time, subsequent calls may not do so. This is
caused by client side attribute caching, because most if not all NFS
clients leave st_atime (last file access time) updates to the server,
and client side reads satisfied from the client's cache will not cause
st_atime updates on the server as there are no server-side reads. UNIX
semantics can be obtained by disabling client-side attribute caching,
but in most situations this will substantially increase server load and
decrease performance.
BUGS
According to POSIX.1-2008/SUSv4 Section XSI 2.9.7 ("Thread Interactions
with Regular File Operations"):
All of the following functions shall be atomic with respect to each
other in the effects specified in POSIX.1-2008 when they operate on
regular files or symbolic links: ...
Among the APIs subsequently listed are read() and readv(2). And among
the effects that should be atomic across threads (and processes) are
updates of the file offset. However, on Linux before version 3.14,
this was not the case: if two processes that share an open file
description (see open(2)) perform a read() (or readv(2)) at the same
time, then the I/O operations were not atomic with respect updating the
file offset, with the result that the reads in the two processes might
(incorrectly) overlap in the blocks of data that they obtained. This
problem was fixed in Linux 3.14.
SEE ALSO
close(2), fcntl(2), ioctl(2), lseek(2), open(2), pread(2), readdir(2),
readlink(2), readv(2), select(2), write(2), fread(3)
COLOPHON
This page is part of release 4.04 of the Linux man-pages project. A
description of the project, information about reporting bugs, and the
latest version of this page, can be found at
http://www.kernel.org/doc/man-pages/.
Linux 2015-07-23 READ(2)
pourtant je francise le man en post install... bon ça c'est pas trop un problème... mais on parle bien de read là ?
et help est très limité...
kiki@Sat-L500:~$ read -H
bash: read: -H : option non valable
read : utilisation : read [-ers] [-a tableau] [-d delim] [-i texte] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [nom ...]
kiki@Sat-L500:~$ read --help
bash: read: -- : option non valable
read : utilisation : read [-ers] [-a tableau] [-d delim] [-i texte] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [nom ...]
Watael a écritles guillemets sont facultatifs entre double-crochets.
== est à réserver aux double-crochets.
et je n'ai pas l'impression que tu utilises de fonctionnalités avancées des double-crochets; leur emploi est alors inutile.
Donc, oui... j'ai tout repassé en simple crochet et supprimer un double == qui traînait... certainement un reste de mes cours de python lol
Par contre... tu m'intéresses... j'ai l'impression que tu as affiné ta compréhension de l'utilisation des simples et doubles crochets... sans doute depuis pas mal de temps maintenant mais ça faisait un moment que je ne t'avais pas croisé et j'ai eu l'impression lors de l'écriture de ma page sur le bash que tu étais encore un peu incertain là dessus... des nouveautés ? le man de test à évolué ?
Watael a écritil faut mettre des guillemets autour de $@ pour éviter les découpages en mots et respecter le parcours des éléments d'un tableau (oui, $@ est un tableau).
Bon là c'est plus simple si c'est une règle unique et immuable !
on dit quoi alors ?
$@ =>
"$@"... pour le parcours d'un tableau... ok ça j'avais bien pigé mais justement je jongle un peu et j'avais même pris l'habitude de ne pas les mettre...
je m'explique :
je te résume : je crée deux listes et des facons différentes de les itérer par deux avec et sans les guillemets
la première liste et les deux premiers exemples sont sans intéret...
#!/bin/bash
# ----------------------------------------------
# test bash et guillemets dans tableaux
# ----------------------------------------------
une_liste="un deux trois cat"
ligne="==========================="
echo "façon 1"
for une_ligne in $une_liste
do
echo $une_ligne
done
echo "$ligne"
echo "façon 2"
for une_ligne in "$une_liste"
do
echo $une_ligne
done
echo "$ligne"
jusque là facile et même sans intéret
façon 1
un
deux
trois
cat
===========================
façon 2
un deux trois cat
===========================
voilà pour l'introduction plus que basique...
mais, si je passe à la ligne, je met plusieurs mots sur une ligne, je saute même une ligne histoire de compliquer un peu le truc...
une_liste="un
deux
trois
cat le chat
et quinte"
# l'espace avant cette ligne est exprès !
echo "façon 3"
for une_ligne in $une_liste
do
echo $une_ligne
done
echo "$ligne"
echo "façon 4"
for une_ligne in "$une_liste"
do
echo $une_ligne
done
echo "$ligne"
là tout est dans les choux... mais c'est normal puisque je ne suis aucune règle d'écriture !
façon 3
un
deux
trois
cat
le
chat
et
quinte
===========================
façon 4
un deux trois cat le chat et quinte
===========================
jusqu'à présent j'ai écrit du code de sagouin... on est d'accord....
mais :
echo "façon 5"
IFS=$'\n'
for une_ligne in "${une_liste[@]}"
do
echo $une_ligne
done
echo "$ligne"
echo "façon 6"
for une_ligne in ${une_liste[@]}
do
echo $une_ligne
done
echo "$ligne"
façon 5
un deux trois cat le chat et quinte
===========================
façon 6
un
deux
trois
cat le chat
et quinte
===========================
et façon 6 en général est ce que je cherche... éclater une liste en ligne ...
Tout cela pour t'expliquer pourquoi je ne quotte plus mes variables en tableau quand je veux les itérer...
et là tu me dis : "oui mais avec $@ on met les doubles quottes... c'est ça ?"
... parce que, moi, j'avis cru comprendre le contraire...
et comme j'ai un petit pois en guise de cerveau... je retest à chaque fois... et j'en reviens toujours à cette façon d'écrire mes itérations en bash...
et quand je dis que je suis un con, ce n'est pas un euphémisme...
tu te doutes de ce que j'ai fait !!! ... et du résultat ?
parce que moi avant de faire le test, j'aurais été parfaitement incapable de dire pourquoi et comment on arrive à ce genre de sortie...
parlons en, si tu veux bien :
#!/bin/bash
# ----------------------------------------------
# test bash et guillemets dans tableaux
# ----------------------------------------------
ligne="==========================="
une_liste="un
deux
trois
cat le chat
et quinte"
fonction_de_la_mort(){
IFS=$'\n'
for une_ligne in "${@}"
do
echo $une_ligne
done
}
fonction_de_la_muerte(){
IFS=$'\n'
for une_ligne in ${@}
do
echo $une_ligne
done
}
echo "façon 7"
fonction_de_la_mort "$une_liste"
echo "$ligne"
echo "façon 8"
fonction_de_la_mort $une_liste
echo "$ligne"
echo "façon 9"
fonction_de_la_muerte "$une_liste"
echo "$ligne"
echo "façon 10"
fonction_de_la_muerte $une_liste
echo "$ligne"
la 7 est dans les choux et les trois autres tiennent tout juste la route...
(puisque dans aucune je ne retrouve mon fameux saut de ligne)
donc la sortie :
façon 7
un deux trois cat le chat et quinte
===========================
façon 8
un
deux
trois
cat le chat
et quinte
===========================
façon 9
un
deux
trois
cat le chat
et quinte
===========================
façon 10
un
deux
trois
cat le chat
et quinte
===========================
et bien sûr, j'ai fait sans toucher à IFS mais on passe en coupure avec les trois séparateurs : espaces / tab / saut de ligne
... si je me rappelle encore de mon mooc de bash...
... et donc, comme c'était trop capillotracté pour moi, j'avais retenue une règle : ne jamais quotter pour itérer sur les tableaux...
mais j'ai encore dû comprendre un truc de travers...
Watael a écritet s'il y a des fichiers qui portent le même nom ?
Alors oui, en effet, je n'ai pas envisagé cette éventualité car, je pensais que ce genre de script est plutôt à utiliser quand on laisse s'entasser des centaines ou milliers de fichiers dans un dossier que l'on veut dispatcher vite fait avant de les traiter après coup...
... je ne sais pas si je m'explique bien...
c'est vrai qu'on est susceptible de se retrouver avec des doublons si nos dossiers sont déjà créés et qu'on ajoute après coup d'autres fichiers que l'on organise dans une seconde passe (ou x ième passe d'ailleurs)... genre utilisation du dossier magique... tu me donnes des idées là !
donc je vais ajouter une routine pour gérer les doublons éventuels... bien vu...
merci de ton assiduité et ta patience Watael 😉