Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

attente touche dans script linux

7 réponses
Avatar
Jean-Pierre
bonsoir à tous,

je viens de découvrir vraiment l'incroyable puissance (et surtout le côté
100 fois plus pratique) de la ligne de commande par rapport justement aux
cliquodromes cités récemment et existant également sous linux.
Pour l'instant c'est l'aspect scanner qui m'intéresse (avec scanimage):
seulement pour le rendre vraiment pratique j'ai besoin dans mon sript de
savoir faire 2 choses:
1) créer l'attente de l'appui sur une touche sans passer par la touche
ENTREE; c'est-à-dire comment faire pour soit juste appuyer sur une touche
précise soit appuyer sur une touche quelconque en la capturant dans une
variable et continuer le script?
2) créer une liste de choix dans un terminal sur plusieurs colonnes à
partir d'une liste dans un fichier (ou plus généralement contrôler
l'affichage dans un terminal)

Le but du jeu étant de me créer un script pour chaque type de scan que je
désire et taïau! je double-clique sur le raccourci je rentre mon nom de
fichier tout en choisissant l'ouverture du fichier dans un programme ou la
simple fin du script en enregistrant le fichier dans un dossier choisi
dans une liste.
Pour moi, c'est simple, c'est du délire par rapport à toutes les usines à
gaz que j'ai connu jusqu'ici que ce soit sous windows ou linux où il faut
lancer les programmes cliquer 36 fois dans 36 onglets et sous-fenêtres à
la noix! ouais vraiment du délire!!!... (pourquoi faire simple quand on
peut faire compliqué!!??)

merci pour vos enseignements!
Jean-Pierre.

7 réponses

Avatar
Pascal Bourguignon
Jean-Pierre writes:

bonsoir à tous,

je viens de découvrir vraiment l'incroyable puissance (et surtout le
côté 100 fois plus pratique) de la ligne de commande par rapport
justement aux cliquodromes cités récemment et existant également sous
linux.
Pour l'instant c'est l'aspect scanner qui m'intéresse (avec
scanimage): seulement pour le rendre vraiment pratique j'ai besoin
dans mon sript de savoir faire 2 choses:

1) créer l'attente de l'appui sur une touche sans passer par la touche
ENTREE; c'est-à-dire comment faire pour soit juste appuyer sur une
touche précise soit appuyer sur une touche quelconque en la capturant
dans une variable et continuer le script?



bash -c 'read -n 1 ch'

(ou si on est dans un script bash, simplement:

read -n 1 ch
)


2) créer une liste de choix dans un terminal sur plusieurs colonnes à
partir d'une liste dans un fichier (ou plus généralement contrôler
l'affichage dans un terminal)


C'est possible.

Une des difficultés en shell, c'est qu'on n'a pas accès à curses. Il
faudrait faire un petit programme comme wish (tcl/tk) mais utilisant
curses au lieu de X...

Alors tu as cinq choix:

- apprendre tcl/tk, utiliser wish et l'interface utilisateur graphique
(qu'on peut trés bien n'utiliser qu'avec du texte, comme le fait
emacs sur X).

(-) c'est plus du pur CLI.
(+) ça marche bien
(+) wish et tcl/tk sont portés sur toutes les plateformes
actuelles.


- apprendre la programmation unix/C et modifier wish pour
travailler avec curses.

(-) y a du boulot.
(+) ça reste du CLI.
(+) ça marche bien
(+) wish et tcl/tk sont portés sur toutes les plateformes
actuelles.


- utiliser dans ton shell des séquences de commandes spécifiques
au model de terminal que tu utilise.

(+) pas trop difficile (voir mon fichier ~/.ansicode ci dessous).
(-) ça ne fonctionne plus dès qu'on utilise un autre terminal
(par exemple, ça ne marche pas dans emacs shell, puisque
c'est un terminal dumb).


- programmer en shell l'analyse des fichiers termcap ou terminfo
pour utiliser les séquences de commandes propres au terminal
indiqué par la variable d'environnement TERM.

(-) bonjour le boulot pour implémenter ça en shell.
(-) ça fait double emploi avec curses.


- ne pas utiliser de séquences de commandes.

(+) c'est le plus simple
(+) ça fonctionne avec tous les terminaux et partout.


Quelque chose du genre:

menu_items=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m")
menu_lines=3
menu_span=$(( ( $menu_lines - 1 + ${#menu_items[@]} ) / $menu_lines ))
column_width=$(( 80 / $menu_span ))
i=0
while [ $i -lt $menu_lines ] ; do
j=$i
while [ $j -lt ${#menu_items[@]} ] ; do
printf "%-${column_width}s" ${menu_items[$j]}
j=$(( $j + $menu_lines ))
done
printf "n"
i=$(( $i + 1 ))
done


Le but du jeu étant de me créer un script pour chaque type de scan que
je désire et taïau! je double-clique sur le raccourci


Ah mais ça c'est plus du CLI, si tu clique !

Faire:

menu_items=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m")
menu_lines=3
menu_span=$(( ( $menu_lines - 1 + ${#menu_items[@]} ) / $menu_lines ))
column_width=$(( 80 / $menu_span ))
format="%2d %-$(( ${column_width} - 3 ))s"
i=0
while [ $i -lt $menu_lines ] ; do
j=$i
while [ $j -lt ${#menu_items[@]} ] ; do
printf "$format" $j ${menu_items[$j]}
j=$(( $j + $menu_lines ))
done
printf "n"
i=$(( $i + 1 ))
done
echo -n "Enter the file name or number: "
read namonum
if [ -z ${namonum//[0-9]} ] ; then
file="${menu_items[$namonum]}"
else
file="$namonum"
fi
echo file=$file

Taper un chiffre et RETOUR,  ça devrait être plus simple que d'aller
chercher la souris pour faire un copier-coller...

je rentre mon
nom de fichier tout en choisissant l'ouverture du fichier dans un
programme ou la simple fin du script en enregistrant le fichier dans
un dossier choisi dans une liste.
Pour moi, c'est simple, c'est du délire par rapport à toutes les
usines à gaz que j'ai connu jusqu'ici que ce soit sous windows ou
linux où il faut lancer les programmes cliquer 36 fois dans 36
onglets et sous-fenêtres à la noix! ouais vraiment du
délire!!!... (pourquoi faire simple quand on peut faire compliqué!!??)

merci pour vos enseignements!
Jean-Pierre.



$ cat ~/.ansicode
export CSI="["
export CYAN_BACK="${CSI}46m"
export MAGENTA_BACK="${CSI}45m"
export BLUE_BACK="${CSI}44m"
export YELLOW_BACK="${CSI}43m"
export GREEN_BACK="${CSI}42m"
export RED_BACK="${CSI}41m"
export BLACK_BACK="${CSI}40m"
export WHITE_BACK="${CSI}47m"
export WHITE="${CSI}37m"
export CYAN="${CSI}36m"
export MAGENTA="${CSI}35m"
export BLUE="${CSI}34m"
export YELLOW="${CSI}33m"
export GREEN="${CSI}32m"
export RED="${CSI}31m"
export BLACK="${CSI}30m"
export NO_INVERT="${CSI}27m"
export NO_BLINK="${CSI}25m"
export NO_UNDERLINE="${CSI}24m"
export NO_BOLD="${CSI}22m"
export INVERT="${CSI}7m"
export BLINK="${CSI}5m"
export UNDERLINE="${CSI}4m"
export BOLD="${CSI}1m"
export NORMAL="${CSI}0m"
export GOTO_HOME=""
export CLEAR_HOME=" "
export CLEAR_SCREEN="c"
export ISO6429ICH="${CSI}@"
export ISO6429CUU="${CSI}A"
export ISO6429CUD="${CSI}B"
export ISO6429CUF="${CSI}C"
export ISO6429CUB="${CSI}D"
export ISO6429CUP="${CSI}H"
export ISO6429ED="${CSI}J"
export ISO6429EL="${CSI}K"
export ISO6429IL="${CSI}L"
export ISO6429DL="${CSI}M"
export ISO6429DCH="${CSI}P"
export ISO6429SM="${CSI}h"
export ISO6429RM="${CSI}l"


$ cat ~/bin/ansi-test
#!/bin/bash
. ~/.ansicodes

function goto () {
echo -n "${CSI}${1};${2}H"
}

echo "${CLEAR_SCREEN}"
x=0
y=0
for b in WHITE CYAN MAGENTA YELLOW BLUE GREEN RED BLACK ; do
bb="$(echo "$b "|sed -e 's/^(........).*$/1/')"
g=${b}_BACK
for f in WHITE CYAN MAGENTA YELLOW BLUE GREEN RED BLACK ; do
goto $y $x;y=$(( $y + 1 ));if [ $y -eq 16 ];then y=0;x=$(( $x + 20 ));fi
ff="$(echo " $f"|sed -e 's/^.*(........)$/1/')"
echo -n "${!f}${!g}$ff on $bb ${NORMAL}"
done
done
y;x=0
for in in "" INVERT ; do
jin="$(echo "$in "|sed -e 's/^(........).*$/1/')"
for bl in "" BLINK ; do
jbl="$(echo "$bl "|sed -e 's/^(........).*$/1/')"
for un in "" UNDERLINE ; do
jun="$(echo "$un "|sed -e 's/^(........).*$/1/')"
for bo in "" BOLD ; do
jbo="$(echo "$bo "|sed -e 's/^(........).*$/1/')"
goto $y $x;y=$(( $y + 1 ))
echo -n "${!in}${!bl}${!un}${!bo} $jin $jbl $jun $jbo ${NORMAL}"
done
done
done
y;x@
done
echo ''
#### ansi-test -- 2004-02-14 18:39:40 -- pascal ####

--
__Pascal Bourguignon__ http://www.informatimago.com/

Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.

Avatar
Stephane Chazelas
2004-08-25, 20:37(+02), Jean-Pierre:
[...]
2) créer une liste de choix dans un terminal sur plusieurs colonnes à
partir d'une liste dans un fichier (ou plus généralement contrôler
l'affichage dans un terminal)
[...]


Tu as une commande faite expres pour ca: cdialog, parfois
appelee dialog voire gdialog.

Si dialog ne t'apporte pas ce que tu veux, passe a perl et
utilise ses packages Curses.

--
Stephane

Avatar
Jean-Pierre
merci à tous!

et je pense que je vais me mettre au perl car n'étant pas un spécialiste de
la programmation il me semble le plus abordable en plus je trouve ça
passionnant et enrichissant.

Jean-Pierre.
à bientôt.

(Pourquoi faire simple quand on peut faire compliqué!!!...)
Avatar
Stephane Chazelas
2004-08-26, 05:24(+02), Pascal Bourguignon:
[...]
(ou si on est dans un script bash, simplement:

read -n 1 ch
)
[...]

(il faut une version relativement recente de bash).

Si on n'a pas bash (ce qui n'est pas le cas de l'OP) :

old_tty_settings=$(stty -g)
stty -echo -icanon time 0 min 1
ch=$(dd bs=1 count=1 2> /dev/null)
stty "$old_tty_settings"

Avec zsh:

read -k ch

A noter que si la touche frappee est <Ctrl-@> (ou <Ctrl-Space>),
seul zsh fonctionnera.

Si la touche frappee est <Entree>, la solution avec "dd"
retournera une chaine vide.

(voir aussi les options "-isig" ou "raw" de stty pour les
touches qui declenchent l'envoi d'un signal (<Ctrl-C>, <Ctrl-Z>,
<Ctrl->...).

Notez si le shell est suspendu a ce moment la, quand il sera
remis en foreground, ca ne marchera pas forcement, en
particulier si le shell interactif de l'utilisateur,
reinitialise les parametres du terminal (bash, zsh).

--
Stephane

Avatar
Laurent Wacrenier
Stephane Chazelas écrit:

Avec zsh:

read -k ch

A noter que si la touche frappee est <Ctrl-@> (ou <Ctrl-Space>),
seul zsh fonctionnera.


Il faut aussi que la touche ne revoie qu'un octet (donc pas de
séquence d'échappement des touches de fonction ou de caractère UTF-8
sur plusieures octets)

Avatar
Stephane Chazelas
2004-08-26, 09:13(+00), Laurent Wacrenier:
Stephane Chazelas écrit:

Avec zsh:

read -k ch

A noter que si la touche frappee est <Ctrl-@> (ou <Ctrl-Space>),
seul zsh fonctionnera.


Il faut aussi que la touche ne revoie qu'un octet (donc pas de
séquence d'échappement des touches de fonction ou de caractère UTF-8
sur plusieures octets)


Exact.

On peut s'en sortir avec
stty min 1 time 1 -icanon
ch=$(dd bs=8 count=1 2> /dev/null)

Ca prend tous les caracteres (au max 8) entrés tant qu'il ne
s'ecoule pas plus d'un dixieme de seconde entre l'arrivee de
deux d'entre eux (ca peut ne pas marcher tres bien par telnet ou
ssh).

--
Stephane


Avatar
Laurent Wacrenier
Stephane Chazelas écrit:
Ca prend tous les caracteres (au max 8) entrés tant qu'il ne
s'ecoule pas plus d'un dixieme de seconde entre l'arrivee de
deux d'entre eux (ca peut ne pas marcher tres bien par telnet ou
ssh).


Par telnet, ça devrait arriver en un seul paquet si l'algorithme de
Naggle est activé (c'est à dire si l'option TCP_NODELAY n'est pas
mise).

Les problèmes, c'est plutôt pour les terminaux série de faible vitesse
ou peut être sur un émulateur de terminal sur un X11 distant avec
beaucoup de latence (l'algorithme de Naggle est désactivé pour ne pas
perturber l'utilisateur avec des mouvements du pointeur saccadés).