web-dev-qa-db-fra.com

Fenêtre du terminal principal affichant uniquement les commandes

Je perds souvent la trace du flux de commandes en raison de la longue sortie de texte de certaines commandes, donc je voudrais avoir un fenêtre du terminal principal où les commandes utilisateur sont exécutées et autres fenêtres du terminal = ce "pop up" affichant la sortie des commandes puis fermé avec l'utilisation d'un raccourci.

Est-il possible de coder un tel comportement? Des conseils sur la langue à utiliser?

Une interaction encore plus conviviale consisterait pour le terminal à demander s'il doit afficher la sortie en externe s'il dépasse une limite définie par l'utilisateur.

1
Sandro Sivsivadzé

Je connais peu les langages de programmation, mais Bash peut certainement se configurer pour se comporter comme vous le souhaitez, alors voici comment je le ferais.

Configuration générale

Définissez une fonction dans votre fichier ~/.bash_aliases Ou ~/.bashrc Qui vous permet de démarrer votre commande dans un nouveau terminal, par ex.

foo () { ( xterm -hold -e bash -c "$*" & ) ;}

De cette façon, foo echo bar Ouvre un nouveau xterm qui montre juste la sortie de echo bar, Ici ce serait une fenêtre avec juste le mot bar dedans. Une chaîne de commandes doit être citée, par ex. foo "echo bar && echo baz". Vous pouvez remplacer xterm par l'émulateur de terminal de votre choix, mais vous devez comprendre ce qu'est l'option rester ouvert - lire la page man. L'option -e Devrait fonctionner pour chacun d'eux. Notez qu'en tant que nom de fonction, vous pouvez choisir même un seul symbole comme :, _ Ou · (AltR+,).

Explications

  • foo () { … ;} - définit une fonction foo qui fait
  • ( … ) - lancez Dans un sous-shell, cela libère le terminal d'origine afin qu'une nouvelle commande puisse être exécutée même lorsque d'autres terminaux de sortie sont encore ouverts
  • xterm -hold -e … - exécutez xterm, exécutez Et -hold Ouvrez-le une fois la commande terminée
  • bash -c " … " - exécutez la ou les commandes , Nécessaires pour pouvoir exécuter plusieurs commandes
  • $* - correspond à chaque argument de foo = la chaîne complète de commandes après foo

Réglage fin

Fermer la fenêtre du terminal de sortie

Vous pouvez fermer le terminal de sortie à l'aide du raccourci standard de votre environnement de bureau pour cela - Alt+F4 par défaut.

Si vous voulez que le terminal de sortie reste ouvert pendant disons cinq secondes après la commande terminée, vous devez définir la fonction comme suit:

foo () { ( xterm -e bash -c "$* && sleep 5" & ) ;}

Remplacez && Par & Pour que le terminal reste ouvert uniquement jusqu'à la fin de la commande, mais au moins cinq secondes .

Facilitation de la saisie

Utilisation de xdotool (laid et sale, boo)

Cela vous dérangera de taper foo avant chaque commande dans votre terminal principal, donc j'ai mis en place une solution de contournement pour cela - installez xdotool d'abord si nécessaire. Lorsque vous ouvrez votre terminal principal, définissez d'abord cette variable:

Prompt_COMMAND='xdotool type "foo "'

Cela tapera automatiquement foo suivi d'un espace après, mais malheureusement aussi avant chaque nouvelle invite. Il ne vous reste plus qu'à taper votre (chaîne de) commande (s).

Utilisation d'une fonction Perl (très cool)

La question de savoir comment effectuer ce qui suit a été posée sur nix.SE et a obtenu une réponse brillante par Stéphane Chazelas , dont la solution est utilisée ici. Si cela vous aide de quelque manière que ce soit, veuillez visiter la question liée et voter pour sa réponse.

Ajoutez les lignes suivantes à votre fichier ~/.bashrc Et enregistrez-le:

insert() { Perl -le 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@" ;}
auto_enter() { bind $'"\u200b":"\1'$1' \5"'; Prompt_COMMAND="insert $'\u200b'" ;}

Maintenant, lorsque vous ouvrez un nouveau terminal et exécutez auto_enter foo, La chaîne "foo" (avec l'espace ajouté automatiquement) apparaît après chaque nouvelle invite. Si vous tapez quelque chose pendant l'exécution d'une commande, "foo" va être inséré avant même ce texte.

Interaction conviviale

Cette version de la fonction enregistre la sortie dans un fichier temporaire, compte ses lignes et demande à l'utilisateur de l'afficher dans une nouvelle fenêtre:

foo () {
  limit=10 # set line limit
  tf=$(mktemp) # create temp file
  "$@" > $tf # execute command, save output in temp file
  lc=$(wc -l < $tf) # get output's line count
  [ $lc -ge $limit ] && # if line count >= limit then
  ( read -p "The output is $lc lines long, do you want to open it in a new window (y/n)? " yn
    case $yn in
        [Yy]* ) xterm -hold -e "cat $tf" & exit;; # open in new window, send to background and exit
        [Nn]* ) cat $tf; exit;; # print output to stdout and exit
        * ) echo "Please answer yes or no.";; # wrong answer
    esac ) || # else
  cat $tf # print output to stdout
}

Bien sûr, cela peut être hautement modifié et personnalisé, mais je pense que c'est un bon début.

Et maintenant pour quelque chose de complètement différent ™

Une manière totalement différente d'atteindre votre objectif consiste à utiliser la redirection de sortie Shell. who vous donne une liste des terminaux en cours d'exécution, par exemple:

> who
username tty7         2017-09-07 20:46 (:0)
username pts/2        2017-09-07 20:47 (:0)
username pts/1        2017-09-07 21:05 (:0)

Vous pouvez envoyer la sortie à l'un d'eux simplement en ajoutant par exemple > /dev/pts/1 À votre commande, qui bien sûr peut également être utilisée dans une fonction comme indiqué ci-dessus.

Les sessions de l'émulateur de terminal GNOME (gnome-terminal) Ne sont pas affichées par who, néanmoins les appareils pts existent également pour eux. Vous pouvez déterminer les sessions de terminal ouvertes simplement en essayant ou avec ls /dev/pts | sed '/^[0p]/d' À la place.

7
dessert