17

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.

e.g.

$ 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 .}
12

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

  • 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
12

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.

  • 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
7

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
1

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

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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