Say I have this:
foo="bar"
echo "\$foo"
That won't work because it will escape the $.
I just want to concatenate the backslash with the content of variable foo.
One way is mentioned by h0ch5tr4355 in a comment, another way you can try if you just want to print and concern with out put then you can try this.
#!/bin/bash
foo="bar"
echo '\'$foo
As mentioned in comment, I am also expecting that you try print foo instead of bar, as bar is empty.
Single-Quotes
Double-Quotes
Yeah this was a dumb question, one solution is as simple as:
foo='bar'
back_slash='\'
echo "$back_slash$foo"
or if you want to be extra careful:
echo "${back_slash}${foo}"
Related
The question is basically, how does bash deal with double quotes and brackets?
I couldn't come up with a better example, so apologies about that, but imagine something like this:
"$(echo "${foo}")"
What happens there? Is ${foo} technically out of the quotation scope? Is bash smart enough to also consider that it is inside of the parentheses and work inside-out? Would \"${foo}\" work better?
I've tried Googling this, but no luck. Please note that this is different from just nested quoting questions, as it includes expansion.
Thanks!
Each command substitution establishes a new quoting context, so the correct way to avoid word splitting inside nested command substitutions is to use double quotes.
In this example, white space is preserved:
$ echo "$(echo "$(echo 'foo bar')")" # outer echo sees 'foo bar'
foo bar
However, missing any of the double quotes means that the string is split by the shell:
$ echo $(echo "$(echo 'foo bar')") # outer echo sees 'foo' 'bar'
foo bar
$ echo "$(echo $(echo 'foo bar'))" # middle echo sees 'foo' 'bar'
foo bar
echo outputs each argument, separated by a spaces, which is where the single space between "foo" and "bar" comes from.
The example you gave does save you from word splitting completely:
"$(echo "${foo}")"
while,
"$(echo ${foo})"
would save you from word splitting on the output but not on the variable $foo.
$() opens a subshell and you need to quote your vars in this subshell too. Consider the following example:
"$(echo "$(echo "$foo")")"
None of the pair of quotes above is optional, if you miss any of them, you will be subject to word splitting.
Consider another example:
"$foo var in same shell, $(cmd) - this output is also in the same shell"
In above, $foo and the output of cmd are safe, but if the cmd includes another variable inside $(), then that variable will need to be quoted.
What is foo? Is it a value? try
"$(echo "$\{foo\}")"
I have looked at this question, but it does not cover my use case.
Suppose I have the variable foo which holds the four-character literal \x60.
I want to perform ANSI C Quoting on the contents of this variable and store it into another variable bar.
I tried the following, but none of them achieved the desired effect.
bar=$'$foo'
echo $bar
bar=$"$foo"
echo $bar
Output:
$foo
\x61
Desired output (actual value of \x61):
a
How might I achieve this in the general case, including non-printable characters? Note that in this case a was used just as an example to make it easier to test whether the method worked.
By far the simplest solution, if you are using bash:
printf %b "$foo"
Or, to save it in another variable name bar:
printf -v bar %b "$foo"
From help printf:
In addition to the standard format specifications described in printf(1)
and printf(3), printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
There are edge cases, though:
\c terminates output, backslashes in \', \", and \? are not removed,
and octal escapes beginning with \0 may contain up to four digits
The following works:
eval bar=\$\'$x\'
The command bar=$'\x61' has to be constructed first, then eval evaluates the newly built command.
I just found out that I can do this. Edited based on comments.
bar=$( echo -ne "$foo" )
The best method I know is
y=$(printf $(echo "$foo"|sed 's/%/%%/g'))
As mentioned in the comments, this trims trailing newlines from $foo. To overcome this:
moo=$(echo "${foo}:end"|sed 's/%/%%/g')
moo=$(printf "$moo")
moo=${moo%:end}
# the escaped string is in $moo
echo "+++${moo}---"
Since bash 4.4 there is a variable expansion to do exactly that:
$ foo='\x61'; echo "$foo" "${foo#E}"
\x61 a
To set another variable use:
$ printf -v bar "${foo#E}"; echo "$bar"
a
Sample of conversion via shell. Problem, the code is octal using \0nnn and hexdecimal (not on all shell) using \xnn (where n are [hexa]digit)
foo="\65"
print "$( echo "$foo" | sed 's/\\/&0/' )"
5
with awk, you could certainly convert it directly
Let's say there is one script s1, and I need to pass argument $1 with value foo bar, with space in it. This can be done
./s1 "foo bar"
however, when I want to run the above command in another script (say s2), how should I put it? If I put it as above, foo bar will be interpreted as two arguments (to s1) rather than one.
You can try quoting $1:
./s2 "$1"
Use single quotes.
./script 'this is a line'
To consider variable substitutions use double quotes
./script "this is a line"
How about:
./s1 foo\ bar
Would that work?
This question already has answers here:
Dynamic variable names in Bash
(19 answers)
Closed 6 years ago.
I want to declare a variable, the name of which comes from the value of another variable, and I wrote the following piece of code:
a="bbb"
$a="ccc"
but it didn't work. What's the right way to get this job done?
eval is used for this, but if you do it naively, there are going to be nasty escaping issues. This sort of thing is generally safe:
name_of_variable=abc
eval $name_of_variable="simpleword" # abc set to simpleword
This breaks:
eval $name_of_variable="word splitting occurs"
The fix:
eval $name_of_variable="\"word splitting occurs\"" # not anymore
The ultimate fix: put the text you want to assign into a variable. Let's call it safevariable. Then you can do this:
eval $name_of_variable=\$safevariable # note escaped dollar sign
Escaping the dollar sign solves all escape issues. The dollar sign survives verbatim into the eval function, which will effectively perform this:
eval 'abc=$safevariable' # dollar sign now comes to life inside eval!
And of course this assignment is immune to everything. safevariable can contain *, spaces, $, etc. (The caveat being that we're assuming name_of_variable contains nothing but a valid variable name, and one we are free to use: not something special.)
You can use declare and !, like this:
John="nice guy"
programmer=John
echo ${!programmer} # echos nice guy
Second example:
programmer=Ines
declare $programmer="nice gal"
echo $Ines # echos nice gal
This might work for you:
foo=bar
declare $foo=baz
echo $bar
baz
or this:
foo=bar
read $foo <<<"baz"
echo $bar
baz
You could make use of eval for this.
Example:
$ a="bbb"
$ eval $a="ccc"
$ echo $bbb
ccc
Hope this helps!
If you want to get the value of the variable instead of setting it you can do this
var_name1="var_name2"
var_name2=value_you_want
eval temp_var=\$$var_name1
echo "$temp_var"
You can read about it here indirect references.
You can assign a value to a variable using simple assignment using a value from another variable like so:
#!/usr/bin/bash
#variable one
a="one"
echo "Variable a is $a"
#variable two with a's variable
b="$a"
echo "Variable b is $b"
#change a
a="two"
echo "Variable a is $a"
echo "Variable b is $b"
The output of that is this:
Variable a is one
Variable b is one
Variable a is two
Variable b is one
So just be sure to assign it like this b="$a" and you should be good.
If I have a variable containing an unescaped dollar sign, is there any way I can echo the entire contents of the variable?
For example something calls a script:
./script.sh "test1$test2"
and then if I want to use the parameter it gets "truncated" like so:
echo ${1}
test1
Of course single-quoting the varaible name doesn't help. I can't figure out how to quote it so that I can at least escape the dollar sign myself once the script recieves the parameter.
The problem is that script receives "test1" in the first place and it cannot possibly know that there was a reference to an empty (undeclared) variable. You have to escape the $ before passing it to the script, like this:
./script.sh "test1\$test2"
Or use single quotes ' like this:
./script.sh 'test1$test2'
In which case bash will not expand variables from that parameter string.
The variable is replaced before the script is run.
./script.sh 'test1$test2'
by using single quotes , meta characters like $ will retain its literal value. If double quotes are used, variable names will get interpolated.
As Ignacio told you, the variable is replaced, so your scripts gets ./script.sh test1 as values for $0 and $1.
But even in the case you had used literal quotes to pass the argument, you shoudl always quote "$1" in your echo "${1}". This is a good practice.