4 votes

Bash : Comment afficher la commande à l'invite suivante pour que l'utilisateur puisse l'utiliser ?

Dans un bash script, je veux sortir une commande à la fin, de sorte que l'utilisateur n'ait qu'à appuyer sur Enter après que mon script se soit terminé pour exécuter cette commande.

Par exemple, l'utilisateur doit exécuter une commande avec certains paramètres. Au lieu de la taper lui-même, mon script sort la commande, avec les paramètres sur sa ligne de commande, puis sort. A ce stade, mon script est terminé. L'utilisateur voit une nouvelle invite, avec la commande "pré-écrite".

Ce gif devrait donner une idée de ce dont je parle :

example

J'ai constaté ce comportement dans plusieurs programmes comme hstr y qfc et je pense que même la norme Recherche inversée le fait.

J'ai cherché sur Google tout ce à quoi je pouvais penser, mais je ne trouve pas de réponse.

3voto

MariusMatutiae Points 45233

Ajoutez ces lignes à la fin de votre script bash :

MY_COMMAND="ls"
MY_PARAMS=()
read -a MY_PARAMS -p $MY_COMMAND 
exec $MY_COMMAND ${MY_PARAMS[@]}

Cela suppose que la commande que vous voulez exécuter est ls vous pouvez le modifier à votre guise. Ce que vous entrez est stocké dans un tableau appelé MY_PARAMS La commande est ensuite exécutée en répétant la commande suivie de l'expansion de la variable tableau, c'est-à-dire de tous ses éléments. Ce qui précède est indépendant du nombre d'éléments que vous passez à votre commande. La commande exec Shell remplace le Shell par la commande donnée, mettant effectivement fin à votre Shell.

EDITAR :

Si vous souhaitez ajouter des capacités complètes d'édition de commandes à votre script, bien au-delà de ce que la lire -e vous pouvez procéder de la manière suivante : installez rlwrap puis ajoutez le code suivant au bas de votre script Bash :

stty -ixon
MYINPUT=()
HISTORY=$HOME/.bash_history
MYCOMMAND="ls"
MYINPUT=$(rlwrap -H $HISTORY -P $MYCOMMAND sh -c 'read REPLY && echo $REPLY')
stty ixon
exec sh -c "${MYINPUT[@]}"

rlwrap est un programme qui est capable d'utiliser toutes les fonctionnalités de ligne de lecture contrairement aux très pauvres Bash lire -e option. Elle vous permet de spécifier un fichier où chercher les complétions possibles (j'ai utilisé l'historique Bash, $HOME/.bash_history ci-dessus, mais vous pouvez écrire votre propre fichier). Il peut également être configuré (voir le inputrc section dans le manuel readline ) afin que vous puissiez choisir entre Emacs -style et vi -et vous permet de rechercher des correspondances en avant ( Ctrl + r ) ou en arrière ( Ctrl + s ) dans le fichier d'historique, modifier les commandes, et bien plus encore.

J'ai ajouté le stty -ixon/set ixon car la plupart des émulateurs de terminaux interceptent les séquences de contrôle. Ctrl + r y Ctrl + s et ainsi de suite, ce qui désactive cette fonctionnalité pour le moment.

Aussi, la commande que vous souhaitez (j'ai utilisé ls à titre d'exemple) est préchargé et peut être exécuté. en l'état (en appuyant sur la touche retour) ou modifié via la fonction ligne de lecture capacités de rlwrap .

Ce qui précède ne peut pas consiste à afficher une liste de correspondances possibles, ce qui vous permet de faire votre choix à l'aide de votre clavier. Cela nécessite un peu de programmation BASH (voir dirkt Réponse de l'UE).

3voto

harrymc Points 394411

Si vous utilisez X, le xdotool pourrait être une solution, en incluant dans le script une commande telle que :

xdotool type command-line-to-display

Si le nouveau texte est mélangé à la sortie du script, quelques acrobaties peuvent être nécessaires. nécessaires.

1voto

dirkt Points 15364

Pas une réponse complète, mais une explication de ce que vous avez vu :

Vous pouvez jeter un coup d'œil à la façon dont qfc procède en inspectant qfc.sh . Il utilise les caractéristiques spéciales de deux coquilles : Pour zsh le zle et pour bash le READLINE_LINE variable. De plus, les deux variantes utilisent une fonction qui est invoquée dans le Shell, elles ne se contentent pas de lancer un Shell et de rendre cette information disponible à la sortie.

Le faire d'une manière Shell-indépendante à la sortie d'un Shell est un problème intéressant. :-)

0voto

pause ?

L'invite de commande dans Windows a le pause qui pourrait faire ce que vous voulez accomplir.

Le message "Appuyez sur n'importe quelle touche pour continuer..." est émis, mais il peut être évité par les moyens suivants pause > nul qui redirige sa propre sortie vers nulle part au lieu de sur l'écran par défaut

0voto

yarl Points 188

Voici une implémentation courte (, moche ?, boguée ?) avec un exemple utilisant/ pour bash.

inline.sh :

inline () {
    stty_backup=$(stty -g)
    #I don't know why exactly, I just faced it
    stty sane
    res=$($READLINE_LINE 3>&1 >/dev/tty)
    stty $stty_backup
    READLINE_LINE=$res
    READLINE_POINT=${#READLINE_LINE}
}
#the bind is Alt-!, you can change it
bind -x '"\e!":"inline"'

hello.sh :

#!/bin/bash
echo Do you want:
echo 1 past?
echo 2 present?
echo 3 futur?

read -p "1 or 2 or 3? " r

if [ "$r" = "1" ]; then r="uptime"
elif [ "$r" = "2" ]; then r="date"
elif [ "$r" = "3" ]; then r="fortune fortunes"
else r=""
fi

echo $r >&3

Votre script doit être assez intelligent, la chaîne de caractères que vous voulez voir renvoyée à votre prompt doit être renvoyée par le fd 3 (voir inline.sh).

Maintenant,

source inline.sh

type

./hello.sh

appuyez sur Alt- !

Vous pouvez source inline.sh dans votre bashrc, bien sûr.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X