Why does the Bourne shell printf iterate over a %s argument?
Question
What's going on here?
printf.sh:
#! /bin/sh
NAME="George W. Bush"
printf "Hello, %s\n" $NAME
Command line session:
$ ./printf.sh
Hello, George
Hello, W.
Hello, Bush
UPDATE: printf "Hello, %s\n" "$NAME"
works. For why I'm not using echo
, consider
echo.sh:
#! /bin/sh
FILE="C:\tmp"
echo "Filename: $FILE"
Command-line:
$ ./echo.sh
Filename: C: mp
The POSIX spec for echo
says, "New applications are encouraged to use printf
instead of echo
" (for this and other reasons).
Solution
Your NAME variable is being substituted like this:
printf "Hello, %s\n" George W. Bush
Use this:
#! /bin/sh
NAME="George W. Bush"
printf "Hello, %s\n" "$NAME"
OTHER TIPS
is there a specific reason you are using printf or would echo work for you as well?
NAME="George W. Bush"
echo "Hello, "$NAME
results in
Hello, George W. Bush
edit: The reason it is iterating over "George W. Bush" is because the bourne shell is space delimitted. To keep using printf you have to put $NAME in double quotes
printf "Hello, %s\n" "$NAME"
The way I interpret the man page is it considers the string you pass it to be an argument; if your string has spaces it thinks you are passing multiple arguments. I believe ColinYounger is correct by surrounding the variable with quotes, which forces the shell to interpret the string as a single argument.
An alternative might be to let printf expand the variable:
printf "Hello, $NAME."
The links are for bash, but I am pretty sure the same holds for sh.
If you want all of those words to be printed out on their own, use print instead of printf
printf takes the formatting specification and applies it to each argument that you pass in. Since you have three arguments {George, W., Bush}, it outputs the string three times using the different arguments.