Blank space in variables in Batch Script in Mac OS [duplicate] - bash

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?

Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.

FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

Related

How to print regex pattern as string in terminal?

I'm trying to write a regex string in the terminal but zsh is interpreting this regex instead of just printing it. My shell code:
echo "((https?:\/\/(?:www\.|(?!www)))?[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})"
Current output:
zsh: event not found: www)))?[a
I already tried to use simple quotes, double quotes and no quotes.
If you type this command in a file and run as a script, it should be fine, unless you have explicitly enabled history expansion in your script. But then, you know what you are doing.
If you really literally hack such a huge command manually into an interactive shell, either turn off history expansion (by setopt nobanghist), or prefix your ! by a \ (unless the ! is already between single-quotes).
Example: Typing echo !www won't work, but typing echo \!www will.
If you never use history expansion, turning it off permanently would probably be the best choice.

Bash tilde not expanding in certain arguments, such as --home_dir=~

Bash is not expanding the ~ character in the argument --home_dir=~. For example:
$ echo --home_dir=~
--home_dir=~
Bash does expand ~ when I leave out the hyphens:
$ echo home_dir=~
home_dir=/home/reedwm
Why does Bash have this behavior? This is irritating, as paths with ~ are not expanded when I specify that path as an argument to a command.
bash is somewhat mistakenly treating home_dir=~ as an assignment. As such, the ~ is eligible for expansion:
Each variable assignment is checked for unquoted tilde-prefixes immediately following a : or the first =. In these cases, tilde expansion is
also performed.
Since --home_dir is not a valid identifier, that string is not mistaken for an assignment.
Arguably, you have uncovered a bug in bash. (I say arguably, because if you use set -k, then home_dir=~ is an assignment, even though it is after, not before, the command name.)
However, when in doubt, quote a string that is meant to be treated literally whether or not it is subject to any sort of shell processing.
echo '--home_dir=~'
Update: This is intentional, according to the maintainer, to allow assignment-like argument for commands like make to take advantage of tilde-expansion. (And commands like export, which for some reason I was thinking were special because they are builtins, but tilde expansion would have to occur before the actual command is necessarily known.)
Like chepner says in their answer, according to the documentation, it shouldn't expand it even in echo home_dir=~. But for some reason it does expand it in any word that even looks like an assignment, and has done so at least as far back as in 3.2.
Most other shells also don't expand the tilde except in cases where it really is at the start of the word, so depending on it working might not be such a good idea.
Use "$HOME" instead if you want it to expand, and "~" if you want a literal tilde. E.g.
$ echo "~" --foo="$HOME"
~ --foo=/home/itvirta
(The more complex cases are harder to do manually, but most of the time it's the running user's own home directory one wants.)
Well, that's because in echo --home_dir=~, the '~' does not begin the word and the output of echo is not considered a variable assignment. Specifically, man bash "Tilde Expansion" provides expansion if
If a word begins with an unquoted tilde character (~); or
variable assignment is checked for unquoted tilde-prefixes immediately following a : or the first =.
You case doesn't qualify as either.

No such file or directory when exporting files using bash script [duplicate]

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

How to create a file/directory from within a function in .bashrc [duplicate]

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

"~/Desktop/test.txt: No such file or directory"

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

Resources