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.

  • Are you certain the problem is the tilde and not the -x option to grep? – Timothy Martin Nov 13 '17 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? – Valentin Bajrami Nov 13 '17 at 19:36
  • @TimothyMartin yes because if i type other paths or just /home/.. instead of ~ it's working. – erans Nov 13 '17 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 Nov 13 '17 at 19:52
  • @erans no, please edit your question, and show exactly what's not working. – Valentin Bajrami Nov 13 '17 at 19:57
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
    Thank you. I couldn't post the rest of the script here but your answer will help me a lot :) – erans Nov 14 '17 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.