7

Is there any way to read raw text from stdin before it is expanded or before the shell does anything to it? Say I wanted to run a script where a user enters a string which is then printed out, how can I get the following behavior:

$ sh test.sh
Please enter a string:
***<><><||&&*&$PATH

You entered:
***<><><||&&*&$PATH

Is there any way to implicitly surround the text with '' or escape all meta characters even if the user does not?

gambol
  • 73
  • 1
  • 1
  • 4
  • Also see [Why is using a shell loop to process text considered bad practice?](http://unix.stackexchange.com/q/169716/135943) In *most* cases, there should be no good reason to use the shell for what you are doing. Perhaps you can, but the shell is *not* a general-purpose programming language. Much like Excel macros are simply the wrong tool to use to attempt to prove or disprove the Riemann Hypothesis. – Wildcard Sep 18 '17 at 20:53

2 Answers2

8

Try doing this :

$ read -r -p 'Please enter a string >>> ' var
$ printf '%q\n' "$var"
\*\*\*\<\>\<\>\<\|\|\&\&\*\&\$PATH
Gilles Quénot
  • 31,569
  • 7
  • 64
  • 82
0

The expansion, if any, is happening when you print, not when you read. (as Giles said, the magic is in the %q. But even echo "$var" is not expanded). Read gets all the literal characters into the variable, except backslash. Echo of the bare variable is expanded. Echo of the variable in a "quote" string is not expanded:

xxmetac.sh:

#!/bin/bash
read str
echo you entered:
echo $str
echo "$str"

test:

$ ls
file1 file2 file3

$ xxmetac.sh
*
you entered:
file1 file2 file3
*

Also most shell metacharacters are not special even when echoed. Probably only the file-globbing ones:

*?[-]{,}

Not special:

!#@$^%()|<>

$ xxmetac.sh
>
you entered:
>
>

$ xxmetac.sh
|
you entered:
|
|

$ xxmetac.sh
@$^%()|<>
you entered:
@$^%()|<>
@$^%()|<>

They are special on the command line

$ !#@$^%()|<>
@$^%()|<>
bash: syntax error near unexpected token `|'