how to escape $ (dollar sign) when echoing environment variable
I am looping through a list of files:
Code:
#!/bin/bash Is there a way to preserve the '$'? I probably need to change that to "dir/\$this file". How can I do that? |
Oh my.
There are a few things wrong with this, but let me ask before we start IS this homework? Because HOW I answer depends upon WHY you are asking. And while I wait for that information: Do you understand how to use "read"? Because that is not how you use "read" in a loop". And the related... Where does the environment variable REPLY get set? Because it is never set in that script. Where does the fileList come from? Has it structure, and what does it look like? WHY in the world have you files containing shell special characters in the names??? Why call 'cat' in this script? Is there some restriction that you must use BASH for this, because it may not be the optimal tool for the job. |
It shouldn't. I tested your script and it prints dollars in filenames just fine on my machine. Weird. Maybe some shopt? Or maybe you simplified the bug out of it?
later: or is it bash at all? Could be busybox, if it's a router or something. What does 'ls -l /bin/bash' say? Quote:
|
The read command without a name variable will automatically save input to $REPLY.
Code:
read Code:
filelist.txt |
Thank you both for that correction. I had always used explicit variables and NEVER used the REPLY variable!
I would still like to see the answers to some of my other questions. OF note, we both want to see the nature of that file. Without understand the input the processing and output are not determined. |
Quote:
|
OK, yes, I simplified the script too much. The problem is with echo. To clarify, fileList is ... a list of files! an example of an entry in this list containing a "$":
Code:
/mnt/public/Pension Files/1 Unpaid Leave-Military Leave/Military Leave reports/~$2023.02.25 Military Leave.xlsx Code:
$ x=$(echo "/mnt/public/Pension Files/1 Unpaid Leave-Military Leave/Military Leave reports/~$2023.02.25 Military Leave.xlsx") So, the real question is how to preserve '$' in an echo and not have echo attempt to replace with an env. variable. To the other questions and comments: Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
So, if anyone has a solution to the echo "$var" problem where var contains '$', I'm still interested. |
x=$(echo "something") is just wrong. I mean it is valid, probably you wanted to do that, but in real life it is just x="something" (usually).
It is not the echo which removes the $, but the syntax you use means you want to evaluate variables within " ". That's why it is removed/evaluated. Actually there was no $2 (it is empty or undefined), therefore you got the result what you posted. But anyway, we cannot show you any solution without knowing your script. At least the relevant part. This cat | while is the typical UUoC (useless use of cat), you should avoid that. Post #4 offers a much better way. |
It's not a problem where var contains '$', it's a quoting problem. To quote bash man page "Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, ...". Use single quotes or xargs.
|
Quote:
I guess you need to sed to add an escape character... |
The use of cat generates an extra I/O call to load cat to do something for which it is not needed.
You can live without it and make your script faster and less vulnerable. Allowing bash to interpret the string causes it to apply regex expansions, causing the problem. Echo, used as you did, is called as a bash internal. It is not needed and adds interpretation. Escaping the character, as you did, is ONE way to avoid that problem. There are others. Not allowing the bash command line handling at your file name data would be optimal. Using a different tool than bash would be another. |
Quote:
I wouldn't bet this is true in other shells (Posix sh, ksh, zsh). Portable is 'while IFS= read var' The empty IFS environment variable makes read preserve leading whitespace. It is a temporary setting just for the read command (technically it happens between fork() and exec()). |
Quote:
Code:
cat fileList | while read And yes, I know I could use other tools. I'm interested specifically in a bash solution. If there isn't one, that's the answer. |
For reading file names use IFS= and -r
Use the built-in string operators (parameter modifiers). Code:
while IFS= read -r fn Code:
x=$(echo "$fn" | sed 's#/mnt##') 100% safe is printf with a format: Code:
x=$(printf "%s\n" "$fn" | sed 's#/mnt##') An assignment (like x=val) does not need quotes (x="val"). But a command does: Code:
printf "%s\n" "$(printf "%s\n" "$fn" | sed 's#/mnt##')" For demonstration, you could write it as Code:
printf "%s\n" "$( |
Quote:
But we would need to know how this variable was generated and if there was any way to make that differently. Quote:
|
All times are GMT -5. The time now is 03:07 PM. |