I wrote a simple script.
read -p "Enter the path: " path
echo "$path"
I give the input as
$HOME
And the output is:
$HOME
And if I write
echo "$HOME"
outputs
/home/sam
so why not in the former case?
I wrote a simple script.
read -p "Enter the path: " path
echo "$path"
I give the input as
$HOME
And the output is:
$HOME
And if I write
echo "$HOME"
outputs
/home/sam
so why not in the former case?
path
becomes the string $PATH
, not the "interpretation" of it. That interpretation only happens in specific contexts – for example, if you type it "bare" on an interactive shell command prompt; but definitely not in read
(otherwise you couldn't use read
to read text files containing $
, for example!).
Remember, expansion is a functionality that you never want to have enabled everywhere – it would make it hard to write programs that pass around variables as variables, instead of their content. Thus, programming language designers (or in the case of shells, decades of more or less organic development) decide where that expansion happens, and where not. There's not really a "why" here: it's how it's defined.
You can eval value="$path"
if you wish, then you get that. I do not recommend that, as it basically makes your entry a shell prompt and if the user enters, for example, $(rm -rf /)
, that would allow them to delete everything...
All in all, I think this is more of a software design problem: what kind of things do you want to allow the user to do?
In this case, $HOME
might pretty much be the only "special" case you'd want to allow. I'd recommend replacing that with ~
, as it's the canonical short form, and do something like:
read "Enter foo bar baz:" raw_path
if [[ ( ! -d "${raw_path}" ) && "${raw_path:0:1}" = "~" ]]; then
_path="${HOME}${raw_path:1:}"
else
_path="${raw_path}"
fi
char *str = "foo()"; printf("%s\n", str);
doesn't call the functionfoo()
. What is read withread
, and what you print withecho
is just data, not shell code. The shell isn't a macro processor that goes back to look at the expanded text to parse it again for further expansions. And it's very well that it isn't, since otherwise people could cause all kinds of havoc with e.g. filenames containing stuff that looks like shell syntax or expansions. – ilkkachu Jan 08 '22 at 14:13echo "$HOME"
gives an output/home/sam
. – klaus_03 Jan 08 '22 at 14:17$HOME
. Same as howecho "$path"
expands$path
. Similar to howprintf("%s\n", foo());
does call the function. It's the difference between code and data. – ilkkachu Jan 08 '22 at 14:20read
function is neither. It simply sets input into a variable. Just as a mental exercise, imagine how dangerous it would be ifread
always evaluated the variables. – jsbillings Jan 08 '22 at 14:25read
without the-r
option does do some mangling of the input data, namely takes backslashes as escapes for field splitting. (which you'd hardly ever want...) But it doesn't evaluate all shell syntax, or even only variable expansions (or quotes, or...) – ilkkachu Jan 08 '22 at 14:31eval printf '%s\n' "$path"
? The use ofeval
is often associated with security risks, so have a look here before using it: https://mywiki.wooledge.org/BashFAQ/048?highlight=%28eval%29 – Valentin Bajrami Jan 08 '22 at 22:22