0

I saw a lot of posts about it all over the internet but i couldn't make it run as i wanted.

I have an input from the user of a path. If the user will type ~/Desktop/ for example i can't use $ans in grep and other commands because of the tilde.

here is an example of my code. the second line is my main problem right now.

read -p "Enter new path or type 'exit':   " ans
file=`grep -x $ans ~/.Log` 

Appreciate your help.

6
  • Are you certain the problem is the tilde and not the -x option to grep? Commented Nov 13, 2017 at 19:36
  • Try file=$(grep -x "$ans" ~/.Log); echo "$file". Also running your little script using bash -xv yourscript what output do you get? Commented Nov 13, 2017 at 19:36
  • @TimothyMartin yes because if i type other paths or just /home/.. instead of ~ it's working.
    – erans
    Commented Nov 13, 2017 at 19:52
  • @val0x00ff read -p "Enter new path or type 'exit': " ans + read -p 'Enter new path or type '\''exit'\'': ' ans. I got this thing. unfortunately your suggestion didn't work :(
    – erans
    Commented Nov 13, 2017 at 19:52
  • @erans no, please edit your question, and show exactly what's not working. Commented Nov 13, 2017 at 19:57

3 Answers 3

1

Several problems here:

  1. You aren't quoting your variable. This means that whatever the user passes in will be subjected (after parameter expansion) to word splitting on whitespace and to glob expansion. This will break things. See:

  2. The user input could start with a hyphen. If it does, it will be interpreted as an option to grep. To avoid this, use the -e option to tell grep that the argument is specifically a search pattern, no matter what it looks like.

  3. You are using regex search. You probably want fixed text search, not regex. So use -F.

  4. Backticks are deprecated. Use $(...) instead. See also:


Putting these points together, you will have code that looks more like:

read -p "Enter new path or type 'exit':   " ans
file="$(grep -Fxe "$ans" ~/.Log)"

But now we come to the additional problems:

  1. The variable file will only contain exactly what the user typed, anyway. Or possibly it will contain nothing. Or possibly it will contain multiple copies of what the user typed, delimited by newlines.

    If we omit the -F flag which I added, then the variable file will only contain full-line matches of the regex the user typed in.

    Neither of these things are necessarily files. The fact that you named the variable file indicates to me that you have some other expectation for what the code does than what it really does in actual fact.

  2. There are also many potential problems associated with using read, which may not matter for your script but you should at least be aware of them; see:

    (Though that post discusses using a shell loop to process text, which you're not doing, it also explains with good examples some of the quirks involved in using read.)

  3. Also, whatever it is that you're doing with that file variable later on could be much more simply accomplished with a pipeline.

I can't take this any further, though, because I don't know what the rest of your script looks like.

1
  • 1
    Thank you. I couldn't post the rest of the script here but your answer will help me a lot :)
    – erans
    Commented Nov 14, 2017 at 15:18
1

Quote wrap the search variable

file=`grep -x "$ans" ~/.Log`

1

See this question and the answers there. It has to do with the order and quoting of shell expansions, specifically tilde expansion. For me the simplest way is my answer there to search and replace ~ with the value of $HOME. So you can add this line before your grep:

ans="${ans//\~/$HOME}"

This is a bashism, but this is tagged with bash.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .