I know there is a specific set of rules that shell expand the commands user typed. (let's talk about bash shell.)

Is it possible to print out a command in the form after shell expansion? It seems to be a good utility to learn and make sure how shell expands special characters.


$ echo *

{all the filenames in current dir}

I want to print out the expanded command, which is the following line:

echo {all the filenames in .}

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

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

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

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).

  • 1
    This is what I do when testing a script – Barmar Jan 6 '15 at 3:00
  • This is still affected by other shell tokens echo cat * | someprogram doesn't do what you might think from this answer. – Kroltan Jan 6 '15 at 11:05

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


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.

  • 2
    And it works fine in an interactive shell, too (which I think the OP is looking for.) – Kundor Jan 6 '15 at 4:36

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).

  • I am using bash from Mac OS. I tried ctrl+x, command+x. I am not sure if it does any command line editing. could you elaborate more? – Weishi Zeng Jan 7 '15 at 10:44
  • @WeishiZeng I don't know why it's not working for you. Did you press Ctrl+x, * immediately after typing echo * and before pressing the enter key? If it still doesn't work, you could modify ~/.inputrc and bind glob-expand-word to something else. – jamesdlin Jan 7 '15 at 18:45
  • contrl+x moves cursor to the word echo, but doesn't edit anything. "Ctrl+x, " what does it mean?? (is it ctrl+x OR ctrl+??) * is on Shift, so I need to press Shift as well to get a *, right? – Weishi Zeng Jan 8 '15 at 22:20
  • Right, press Ctrl+x followed by Shift+8. You could try seing if Ctrl+x, g works, or, as I said earlier, assign your own key in the .inputrc file. – jamesdlin Jan 8 '15 at 22:59

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:


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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.