Est-il possible d'imprimer l'extension du shell?


18

Je sais qu'il existe un ensemble spécifique de règles qui développent les commandes tapées par l'utilisateur. (parlons de shell bash.)

Est-il possible d'imprimer une commande sous la forme après expansion du shell? Cela semble être un bon utilitaire pour apprendre et s'assurer que le shell développe les caractères spéciaux.

par exemple

$ echo *

{all the filenames in current dir}

Je veux imprimer la commande développée, qui est la ligne suivante:

echo {all the filenames in .}

Réponses:


13

Utilisez simplement echo... placez-le devant la commande que vous souhaitez développer. J'utilise cela assez fréquemment.

$ ls
one.txt
two.txt
three.dat
$ echo rm *.txt
rm one.txt two.txt
$ rm *.txt

Vous pouvez utiliser Homeet Delpour ajouter / supprimer rapidement ce qui précède echo.

EDIT
Comme souligné dans les commentaires, cela ne fonctionnera pas si la commande est non seulement une simple commande (comme si elle est une forboucle, utilise le tuyau |, ou &&ou autre chose comme ça).


1
Voici ce que je fais lorsque je teste un script
Barmar

Ceci est toujours affecté par d'autres jetons shell echo cat * | someprogramne fait pas ce que vous pourriez penser de cette réponse.
Kroltan

13

Vous pouvez utiliser set -x.

Par exemple, considérez le script:

$ cat script.sh
set -x
echo *

Lorsqu'il est exécuté, il affiche l' echoinstruction développée avant de l'exécuter:

$ bash script.sh
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

Et, comme le souligne Kundor, cela fonctionne également de manière interactive sur la ligne de commande:

$ set -x
+ set -x
$ echo *
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

Documentation

man bashexplique ce qui se set -xpasse comme suit:

Après avoir développé chaque commande simple, pour la commande, la commande de casse, la commande de sélection ou l'arithmétique de la commande, affichez la valeur développée de PS4, suivie de la commande et de ses arguments développés ou de la liste de mots associée.

PS4Comme indiqué ci-dessus, la valeur par défaut de est un signe plus suivi d'un espace.


2
Et cela fonctionne très bien dans un shell interactif aussi (ce que je pense que l'OP recherche.)
Nick Matteo

7

Pour un shell interactif, appuyer sur Ctrl+xpuis sur *après avoir tapé le modèle glob éditera votre ligne de commande avec ce modèle glob développé. Depuis la page de manuel de bash:

glob-expand-word ( C-x *)

Le mot avant le point est traité comme un modèle pour l'expansion du nom de chemin et la liste des noms de fichiers correspondants est insérée, remplaçant le mot. Si un argument numérique est fourni, un astérisque est ajouté avant l'expansion du nom de chemin.

Vous pourriez également être intéressé par les extensions de la liste globale ( Ctrl+x, g).


J'utilise bash sous Mac OS. J'ai essayé ctrl + x, command + x. Je ne sais pas s'il fait une modification de ligne de commande. pourriez-vous en dire plus?
Weishi Zeng

@WeishiZeng Je ne sais pas pourquoi cela ne fonctionne pas pour vous. Avez-vous appuyé Ctrl+x, *immédiatement après avoir tapé echo *et avant d'appuyer sur la touche Entrée? Si cela ne fonctionne toujours pas, vous pouvez modifier ~/.inputrcet lier glob-expand-word à autre chose.
jamesdlin

contrl + x déplace le curseur sur le mot écho, mais ne modifie rien. "Ctrl + x ", qu'est-ce que cela signifie ?? (est-ce ctrl + x OU ctrl + ??) * est sur Shift, donc je dois également appuyer sur Shift pour obtenir un *, non?
Weishi Zeng

À droite, appuyez sur Ctrl+xsuivi de Shift+8. Vous pouvez essayer de voir si cela Ctrl+x, gfonctionne, ou, comme je l'ai dit plus tôt, attribuer votre propre clé dans le .inputrcfichier.
jamesdlin

1

Si vous souhaitez voir comment les arguments sont développés ou tokenisés, vous pouvez utiliser un programme ou un script qui imprime ses arguments. Voici une implémentation dans bash:

#!/bin/bash

for (( i = 0; i <= $#; ++i )); do
    printf 'argv[%d] = %s\n' $i "${!i}"
done

En supposant que vous mettiez cela dans un fichier appelé printargs.sh(et que vous le rendiez exécutable), vous obtiendrez une sortie comme celle-ci

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.