Why does the Bourne shell printf iterate over a %s argument?

Tags: shell unix
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).



Answers

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"


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.

By : OwenP


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"
By : Tanj


This video can help you solving your question :)
By: admin