Is it possible to print out the shell expansion?

Solution 1:

Just use echo...put it in front of the command you want to expand. I use this quite frequently.

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

You can use Home and Del to quickly add/remove the preceding echo.

EDIT
As pointed out in the comments, this will not work if the command is not just a simple command (like if it is a for loop, uses the pipe |, or && or anything else like that).

Solution 2:

You can use set -x.

For example, consider the script:

$ cat script.sh
set -x
echo *

When run, it shows the expanded echo statement before actually executing it:

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

And, as Kundor points out, this also works interactively on the command line:

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

Documentation

man bash explains what set -x does as follows:

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.

The default value for PS4 is, as shown above, a plus sign followed by a space.

Solution 3:

For an interactive shell, pressing Ctrl+x followed by * after typing the glob pattern will edit your command line with that glob pattern expanded. From the bash man page:

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.

You might also be interested in glob-list-expansions (Ctrl+x, g).

Solution 4:

If you want to see how arguments are expanded or tokenized, you can use a program or script that prints out its arguments. Here's one implementation in bash:

#!/bin/bash

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

Assuming you put that in a file called printargs.sh (and made it executable), then you would get output like this

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