简体   繁体   中英

Bash: “printf %q $str” deletes spaces when in scripts. (Alternatives?)

printf %q should quote a string. However, when executed into a script, it deletes the spaces.

This command:

printf %q "hello world"

outputs:

hello\ world

which is correct.

This script:

#!/bin/bash

str="hello world"
printf %q $str

outputs:

helloworld

which is wrong.

If such behavior is indeed expected, what alternative exists in a script for quoting a string containing any character in a way that it can be translated back to the original by a called program?

Thanks.

Software: GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)

EDITED: Solved, thanks.

You should use:

printf %q "$str"

Example:

susam@nifty:~$ cat a.sh
#!/bin/bash

str="hello world"
printf %q "$str"
susam@nifty:~$ ./a.sh 
hello\ world

When you run printf %q $str , the shell expands it to:

printf %q hello world

So, the strings hello and world are supplied as two separate arguments to the printf command and it prints the two arguments side by side.

But when you run printf %q "$str" , the shell expands it to:

printf %q "hello world"

In this case, the string hello world is supplied as a single argument to the printf command. This is what you want.

Here is something you can experiment with to play with these concepts:

susam@nifty:~$ showargs() { echo "COUNT: $#"; printf "ARG: %s\n" "$@"; }
susam@nifty:~$ showargs hello world
COUNT: 2
ARG: hello
ARG: world
susam@nifty:~$ showargs "hello world"
COUNT: 1
ARG: hello world
susam@nifty:~$ showargs "hello world" "bye world"
COUNT: 2
ARG: hello world
ARG: bye world
susam@nifty:~$ str="hello world"
susam@nifty:~$ showargs $str
COUNT: 2
ARG: hello
ARG: world
susam@nifty:~$ showargs "$str"
COUNT: 1
ARG: hello world

Try

printf %q "${str}"

in your script.

This worked for me. Satisfies these requirements

  1. Accept arbitrary input that may include shell special characters
  2. Does not output escape character, the "\\"
#! /bin/bash

FOO='myTest3$;  t%^&;frog now! and *()"'

FOO=`printf "%q" "$FOO"`                        # Has \ chars
echo $FOO

# Eat all the \ chars
FOO=$(printf "%q" "$FOO" | sed "s/\\\\//g")     # Strip \ chars

echo $FOO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM