É possível imprimir a expansão do shell?

15

Eu sei que existe um conjunto específico de regras que shell expandem os comandos digitados pelo usuário. (vamos falar sobre o bash shell.)

É possível imprimir um comando no formulário após a expansão do shell? Parece ser uma boa utilidade aprender e ter certeza de como o shell expande os caracteres especiais.

por exemplo.

$ echo *

{all the filenames in current dir}

Eu quero imprimir o comando expandido, que é a seguinte linha:

echo {all the filenames in .}
    
por Weishi Zeng 06.01.2015 / 01:51

4 respostas

10

Apenas use echo ... coloque na frente do comando que você deseja expandir. Eu uso isso com bastante frequência.

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

Você pode usar Home e Del para adicionar / remover rapidamente o echo precedente.

EDITAR
Como apontou nos comentários, isso não funcionará se o comando não for apenas um comando simples (como se fosse um for loop, usa o canal | ou && ou qualquer outra coisa como essa).

    
por 06.01.2015 / 02:38
12

Você pode usar set -x .

Por exemplo, considere o script:

$ cat script.sh
set -x
echo *

Quando executado, ele mostra a instrução expandida echo antes de executá-la:

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

E, como Kundor aponta, isso também funciona interativamente na linha de comando:

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

Documentação

man bash explica o que o set -x faz da seguinte forma:

After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of PS4, followed by the command and its expanded arguments or associated word list.

O valor padrão para PS4 é, como mostrado acima, um sinal de mais seguido por um espaço.

    
por 06.01.2015 / 02:22
7

Para um shell interativo, pressionar Ctrl+x seguido por * depois de digitar o padrão glob editará sua linha de comando com esse padrão glob expandido. Da página man bash:

glob-expand-word (C-x *)

The word before point is treated as a pattern for pathname expansion, and the list of matching file names is inserted, replacing the word. If a numeric argument is supplied, an asterisk is appended before pathname expansion.

Você também pode estar interessado em expansões de lista de glob ( Ctrl+x , g ).

    
por 06.01.2015 / 06:23
1

Se você quiser ver como os argumentos são expandidos ou convertidos em tokens, é possível usar um programa ou script que imprima seus argumentos. Aqui está uma implementação em bash :

#!/bin/bash

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

Supondo que você coloque isso em um arquivo chamado printargs.sh (e tornou-o executável), então você obteria uma saída como essa

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
    
por 06.01.2015 / 02:32