Russell Teapot February 2016

Printf splits a string at spaces - Bash

I'm having some troubles with the printf function in bash. I wrote a little script on which I pass a name and two letters (such as "sh", "py", "ht") and it creates a file in the current working directory named "name.extension". For instance, if I execute seed test py a file named test.py is created in the current working dir with the shebang #!/usr/bin/python3.

So far, so good, nothing fancy: I'm learning shell scripting and I thought this could be a simple exercise to test the knowledge gained so far. The problem is when I want to create an HTML file. This is the function that I use:

creaHtml(){
        head='<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>'
        percorso=$CARTELLA_CORRENTE/$NOME_FILE.html
        printf $head>>$percorso
        chmod 755 $percorso

}

If I run, for instance, seed test ht the correct function (creaHtml) is called, test.html is created but if I try to look into it I only see:

<!--DOCTYPE

And nothing else. This is the trace for that function:

[sviluppo:~/bin]$ seed test ht
+ creaHtml
+ head='<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>'
+ percorso=/home/sviluppo/bin/test.html
+ printf '<!--DOCTYPE' 'html-->\n<html>\n\t<head>\n\t\t<meta' 'charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>'
+ chmod 755 /home/sviluppo/bin/test.html
+ set +x

However, if I try to run printf '<!--DOCTYPE html-->\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t</head>\n\t<body>\n\t</body>\n</html>' from the term

Answers


e0k February 2016

Try echo -e instead of printf. printf is for printing formatted strings. Since you didn't protect $head with quotes, bash splits the string to form the command. The first word (before first white space) forms the format string. The rest are just arguments for things you didn't specify to print.

echo -e "$head" > "$percorso"

The -e evaluates your \n into newlines. I changed your >> to > since it looks like you want this to be the whole file, rather than append to any existing file you might have.

You have to be careful with quotes in bash. One thing can become many things. This actually makes it more powerful, but it can be confusing for people learning. Notice that I also put the file name "$percorso" in double quotes too. This evaluates the variable and makes sure that it ends up as one thing. If you use single quotes, it will be one word, but not evaluated. Unlike Python, there is a big difference between single and double quotes.

If you want to use printf for compatibility as @chepner pointed out, just be sure to quote it:

printf "$head" > "$percorso"

Actually that is much simpler anyway.

Post Status

Asked in February 2016
Viewed 2,195 times
Voted 12
Answered 1 times

Search




Leave an answer