My bash script receives a filename (or relative path) as a string, but must then read from that file. I can only read from a filename if I declare it as a literal directly in the script (without quotes)...which is impossible for arguments since they are implicitly strings to begin with. Observe:
a="~/test.txt" #Look for it if [[ -a $a ]] ; then echo "A Found it" else echo "A Error" fi #Try to use it while read line; do echo $line done < $a b='~/test.txt' #Look for it if [[ -a $b ]] ; then echo "B Found it" else echo "B Error" fi #Try to use it while read line; do echo $line done < $b c=~/test.txt #Look for it if [[ -a $c ]] ; then echo "C Found it" else echo "C Error" fi #Try to use it while read line; do echo $line done < $c
YIELDS:
A Error ./test.sh: line 10: ~/test.txt: No such file or directory B Error ./test: line 12: ~/test.txt: No such file or directory C Found it Hello
As stated above, I can't pass a command line argument to the routines above since I get the same behavior that I get on the quoted strings.
However, most users will still have issues while trying to handle passing filenames with spaces in bash. This is because spaces are not considered the same in bash as they are in file names. Why Filename with Spaces is not Recognized by Bash?
domain="example" sub="foo" if [ -f /opt/nginx/conf.d/com_$domain_$sub.conf ] cat <<EOF > /opt/nginx/conf.d/com_$domain_$sub.conf some multiline content EOF fi In this case Bash interprets domain_ as the name of the variable to expand. It's a valid name for a variable. Expanding this name is not what you intended.
Using an unset variable is normally not an error. Invoke set -u and Bash will treat unset variables as errors (revert with set +u if needed). Treating unset variables as errors is useful for debugging, but also in defensive scripting.
To see the active environment variables in your Bash session, use this command: env | less. If you scroll through the list, you might find some that would be useful to reference in your scripts. How to Export Variables. When a script runs, it’s in its own process, and the variables it uses cannot be seen outside of that process.
This is part of the rules of ~
-expansion. It is clearly stated in the Bash manual that this expansion is not performed when the ~
is quoted.
Don't quote the ~
.
file=~/path/to/file
If you need to quote the rest of the filename:
file=~/"path with spaces/to/file"
(This is perfectly legal in a garden-variety shell.)
Use $HOME
instead of ~
.
file="$HOME/path/to/file"
You seem to be a little confused about the types of shell variables.
Everything is a string.
Repeat until it sinks in: Everything is a string. (Except integers, but they're mostly hacks on top of strings AFAIK. And arrays, but they're arrays of strings.)
This is a shell string: "foo"
. So is "42"
. So is 42
. So is foo
. If you don't need to quote things, it's reasonable not to; who wants to type "ls" "-la" "some/dir"
?
Still not as glamorous, but worked for me:
home_folder="/home/$(logname)"
can work from there...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With