BASH: ls commande inconnue

J’ai trouvé ceci, qui semble bien correspondre à ce que je cherche (dans sa forme rapide à explorer):

https://perso.univ-lyon1.fr/jean-patrick.gelas/UE_Systeme/conseils_script_shell/

Bonjour

Quelques liens et documents au sujet de bash :

grymoire Sh

The Art of Unix Programming (by Eric Steven Raymond)

The GNU Bourne-Again SHell (case.edubashtop)

Bash Guide for Beginners (Machtelt Garrels)

Bash Reference Manual

Advanced Bash-Scripting Guide
An in-depth exploration of the art of shell scripting

BashGuide

Linux Documentation Project Guides

Introduction à la programmation en Bash (Eric Sanchis - aral.iut-rodez)

Bash Hackers Wiki Frontpage

Salut MicP,

J’ai été sur ton lien, ça sent la page perso.
Je me permet juste de te dire que les liens sont bleu foncé sur fond foncé et ça pique les yeux.

Un tout grand merci pour ton regroupement d’infos, c’est très utiles.

Pour répondre à ta question josephtux,

le nommage est quelque chose de très important, mais qui malheureusement n’a d’autre manuel que ton imagination et ta logique.

Il y a cependant des conventions de nommage en fonction des languages de programmations, comme en Javascript, BASH, …
Par exemple en bash j’utilise des nom de variable ma_variable , en Javascript maVariable…
Et je m’y tiens tient tout simplement.

En BASH malheureusement on a également tous les programmes systemes dans le PATH, qui peuvent être appelé , j’avais passer des heures à deboger un script de sauvegarde parce que comme un imbécile, j’avais nommer la fonction rsync_backup => qui elle même pointait vers un ALIAS rsync.
Enfin on peut vite se retrouver avec des erreurs étranges, pour cela tu peux également ajouter le -x a ton #!/bin/bash afin de mieux voir ce qu’il se passe.

J’avais également commencé un gros tuto sur bash que tu peux retrouver Mon site

Oui, c’est d’ailleurs pour ça que ça s’appelle les pages perso :slight_smile:
et donc, ces pages web sont adapté à MA vue.

Je n’aurai sans doute pas dû donner ce lien perso,
mais je jais essayer d’arranger ça en essayant de retrouver la source de tous ces liens.

Micp c’était absolument pas une critique mais plutôt une suggestion.
Car à titre personnel, je change ça a la volé dans l’inspecteur.

Rassure-toi, je ne l’ai pas pris négativement, mais comme j’avais eu la flemme de rechercher les liens sur le moment, j’avais simplement donné un lien vers mes pages perso, et donc, c’est logique qu’elles ne puissent pas convenir à tous.

Mais finalement, je viens de prendre le temps de mettre les liens,
et ça a été plus vite fait que je ne le pensais :slight_smile:

Je trouve très étonnant d’extrapoler une règle générale à partir d’un cas extrêmement particulier, à savoir ‹ qu’il ne faudrait jamais utiliser de majuscules pour une nom de variable ›
Dans la même logique, on pourrait dire ‹ qu’il ne faudrait jamais utiliser de minuscules pour un nom de variable ›, puisqu’il existe 1355 risques de confusion avec un nom de commande.

ls /usr/bin |wc -l
1355

echo $(pwd)
echo $PWD

pwd est une commande. PWD est une variable système.

Dans les docs proposées, 10 secondes pour trouver un exemple:
VAR=/usr/lib; export VAR

La seule bonne règle est qu’il ne faut pas ré-utiliser de noms de commandes en minuscules, ou de variables système en majuscules pour éviter toute confusion.

@josephtux
Tu as donc mis 3 jours pour comprendre où était passée la commande ‹ ls ›, il faut donc aller à ton rythme.
Je ne suis pas sûr que tu aies compris que la commande ‹ ls › est en fait explicitement /usr/bin/ls.

Il y a déjà des tonnes de docs bash disponibles, parce-qu’il n’existe pas en fait de doc qui puisse convenir à tout le monde, selon le niveau, et qui soit à jour. Aucune n’est parfaite → c’est pour ça qu’il y en a autant…
Des docs de 2001 ne sont pas à jour, et très ambigües sur certains points, donc perte de temps pour du bash 5.
L’interpréteur de commandes du système Debian de base est dash.

$ readlink /usr/bin/sh
dash

Bash est proposé en plus par défaut car plus évolué (mais plus gourmand en ressources).
zsh en est un autre très puissant qui peut remplacer bash (je suis revenu à bash après des années de zsh).

Bash n’a donc rien de spécifique à Debian, et il y a un fossé entre connaître bash, et l’ensemble des commandes linux, parce-que bash tout seul, sans les commandes linux n’est pas très utile.

La meilleure documentation est celle que tu te feras en fonction de ta progression.
Tu pioches progressivement ce qui te manque dans des docs plus ou moins bien ciblées sur ta recherche, et tu complètes, en pratiquant.
C’est un peu comme le forgeron qui apprend en forgeant.

Pour forger, et revenir au concret, quelques commentaires sur ton script:

1 - dans un script aussi simple, tu aurais pu te passer des variables NOM="$1" DIR="$2", et directement utiliser $1 et $2 dans tout ton script, en précisant seulement en commentaire
# NOM="$1" ; DIR="$2"

2 - à titre d’exercice, tu peux regarder si une solution plus compacte ne parait pas plus conviviale, à savoir:

#!/bin/bash
read -p "NOM ? " NOM
read -p "CHEMIN ? " CHEMIN
ls ${CHEMIN:-$PWD}/$NOM
exit

ou en fonction

fonction1() { read -p "NOM ? " NOM
              read -p "CHEMIN ? " CHEMIN
              ls ${CHEMIN:-$PWD}/$NOM ; }

fonction que tu lances avec
$ fonction1

Il me semble que certaines constructions ne fonctionnent pas avec $1 ,$2 etc. ce qui m’avait fait adopter cette habitude. Mais il y a longtemps, alors que j’étais un débutant un peu plus réactif et j’ai oublié. Peut-être une erreur de ma part déjà à cette époque.
Votre suggestion de commentaire reste intéressante, mais pour un script qui a tendance à s’allonger, je préfère garder un nom plus explicite (au cas ou je modifierai la syntaxe du script, $1 et $2 pourrai changer de signification, comme être décalés ou interverti). Comme vous l’avez constaté, je suis au niveau presque 0 de la programmation, donc au fur et à mesure que j’apprends (et aussi hélas, désapprends!) je peux vouloir modifier beaucoup de choses! C’est aussi vrai dans le cas ou je veux étendre et améliorer le script.

Je ne crois pas avoir écrit «il faut» mais suggéré en attente de critique. La votre reste cependant intéressante. En effet, ce que je cherche c’est à trouver des bonnes pratiques:

  • pour éviter des pièges comme celui de collision/conflit avec des noms existants (variables, fonctions, programmes), en cause dans la question initiale de ce fil,
  • pour faciliter la relecture du script et sa compréhension
  • éventuellement pour adopter des pratiques personnelles de personnes compétentes
  • et pour être aussi plus lisible et compréhensibles par d’autres au cas où il serait utile de partager ce script (je pense à d’autres que moi, lecteurs de cette discussion.)
  • peut être pour d’autres motifs qui m’échappent et qu’il serait pourtant utile de prendre en compte.

Par exemple j’utiliseparfois. certaines notation venant du C, de Java ou autre:

  • je prefixe la variable avec son type (un abrégé du type) afin de me rappeler l’utilité de la variable et son contenu; de fait je suis sur de ne jamais avoir de concomitance avec une variable système ou un executable.
    Par exemple: variable de nom : cNom (variable nom de type char)

c’est parce que je ne connais pas toutes ces commandes ni toutes ces variables, que j’envisage cette règle personnelle.
Est-ce qu’elle présente un inconvénient?
Sinon j’aime nommer les variables (comme mes noms de fichier) avec des majuscules au début de chaque mot composant le nom. Auparavant je mettais comme vous le faites des « _ » pour les séparer, mais ma méthode me suffit pour la lisibilité et raccourcit un peu les noms de fichier plus lisibles également dans les listes (comme ls -l ).

excellente suggestion, qu’il m’arrive d’utiliser presque sans y penser, mais sans en avoir fait un règle. (par exemple variable DirBkp ou fonction CreerDirBkp)
Si j’avais été plus rigoureux, j’aurais d’emblée appliqué cette règle, et cette discussion n’aurait pas eu lieu…

En conclusion, l’écrasement de la variable PATH rendait inaccessible toutes les commandes dont le chemin complet n’était pas donné.
donc

  • il est préférable de ne pas écraser une variable système!
  • il est préférable de donner le chemin complet des commandes et autres fichiers.

Merci à tous pour vos réponses, vos critiques et vos suggestions.

Ce ne sont pas des variables système, mais des variables d’environnement


Le chemin absolu d’un exécutable n’est pas nécessaire, puisqu’il dépends des variables d’environnement qui vont proposer le « bon » chemin en fonction de la configuration du système installé, et que le chemin absolu qui serait imposé dans un script pourrait ne pas correspondre à l’environnement dans lequel le script sera lancé.

En résumé, à moins d’avoir une raison personnelle bien particulière de vouloir utiliser une commande précise dont on connaît parfaitement le chemin absolu, il vaut mieux laisser les variables d’environnement (par exemple : PATH) décider de l’endroit où il faudra aller chercher les commandes à utiliser.

Pour les variables en majuscules, les risques sont extrêmement limités et se limitent essentiellement à « HOME, PATH, PWD, USER » qu’il ne faut pas réaffecter.

env |sort

En notant qu’il n’existe pas de variable environnement majuscule à une seule lettre « A, B …Z », ni aucune en langue française « CHEMIN, REPERTOIRE, DOSSIER etc… », tu n’as vraiment pas eu de chance parmi 1 sur des milliers de combinaisons possibles. Je pense que le sujet du choix des variables est définitivement clos…

Pour en revenir à ton script initial, je n’avais en fait pas vraiment compris pourquoi tu avais besoin de quelque-chose d’aussi compliqué avec 4 variables pour sortir une commande ‹ ls ›, je te propose une variante un peu plus sophistiquée qui contient quelques subtilités qui permettra de vérifier ta progression, en t’appuyant sur la « meilleure » documentation de bash, et non pas de sh à ne pas confondre.

#!/bin/bash
NOM=$1 ; DIR=${2:-.}
until ls ${DIR%/}/$NOM 2>/dev/null ; do
 echo -e '\x1b[31m !! saisie <nom> <répertoire> incorrecte !!\x1b[m'
 [[ -d $DIR ]] || read -p '-> nouveau répertoire ? ' DIR
 [[ -d ${DIR%/}/$NOM ]] || read -p '-> nouveau NOM ? ' NOM
done
exit

il y ena quelqeus autres.
le meilleurs moyen de le savoir, c’est de faire la commende env dans l’environnement correspondant.

Il faut faire attention à IFS aussi.

… et aussi à :

COLORTERM
DBUS_SESSION_BUS_ADDRESS
DESKTOP_SESSION
DISPLAY
GDMSESSION
GTK_MODULES
LANG
LESS_TERMCAP_mb
LESS_TERMCAP_md
LESS_TERMCAP_me
LESS_TERMCAP_se
LESS_TERMCAP_so
LESS_TERMCAP_ue
LESS_TERMCAP_us
LOGNAME
LS_COLORS
PANEL_GDK_CORE_DEVICE_EVENTS
QT_ACCESSIBILITY
SESSION_MANAGER
SHELL
SHLVL
SSH_AGENT_PID
SSH_AUTH_SOCK
TERM
_
VTE_VERSION
WINDOWID
XAUTHORITY
XDG_CONFIG_DIRS
XDG_CURRENT_DESKTOP
XDG_DATA_DIRS
XDG_GREETER_DATA_DIR
XDG_MENU_PREFIX
XDG_RUNTIME_DIR
XDG_SEAT_PATH
XDG_SEAT
XDG_SESSION_CLASS
XDG_SESSION_DESKTOP
XDG_SESSION_ID
XDG_SESSION_PATH
XDG_SESSION_TYPE
XDG_VTNR

réponse générique.

Le mot ‹ essentiellement › ne signifie pas ‹ exclusivement ›, je ne vois aucune ambiguïté.
Les mots « HOME, PATH, PWD, USER » sont juste les plus à risque, intuitivement.
Il faut quand-même avoir un esprit extrêmement tordu pour nommer un répertoire ‹ PANEL_GDK_CORE_DEVICE_EVENTS › ou ‹ QT_ACCESSIBILITY ›, à moins de vraiment chercher volontairement les emmerdes (on a quand-même l’impression que c’est le cas de certains).
Et quand-bien même, il y aurait un bug: oulala.
Quand il y un bug, on cherche et on trouve, et on ne passe pas 1 semaine sur un forum pour comprendre au bout de 20 messages.

env |sort que j’ai cité n’enlève aucune variable.
‹ Sort › est juste un filtre pour trier la liste pour meilleure lisibilité.

Et pour les variables en minuscule, if faut faire :
ls /usr/bin /bin $HOME/bin
pour s’assurer de ne pas utliser un nom de commande comme variable.

Je n’aurais jamais imaginé de telles interrogations pour juste nommer une variable, qui n’est vraiment que le tout début de l’apprentissage du bash.
Si ce n’est pas encore suffisemment clair, je ne vois pas quoi rajouter sur un sujet ‹ variable › que je pensais définitivement clos.