Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expansion of variables inside single quotes in a command in Bash

I want to run a command from a bash script which has single quotes and some other commands inside the single quotes and a variable.

e.g. repo forall -c '....$variable'

In this format, $ is escaped and the variable is not expanded.

I tried the following variations but they were rejected:

repo forall -c '...."$variable" '  repo forall -c " '....$variable' "  " repo forall -c '....$variable' "  repo forall -c "'" ....$variable "'" 

If I substitute the value in place of the variable the command is executed just fine.

Please tell me where am I going wrong.

like image 367
Rachit Avatar asked Dec 10 '12 11:12

Rachit


People also ask

How do you pass variables in single quotes in bash?

If the backslash ( \ ) is used before the single quote then the value of the variable will be printed with single quote.

Can you use single quotes in bash?

Enclosing characters in single quotes (' ' ') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

What does $# mean in bash script?

$# is the number of positional parameters passed to the script, shell, or shell function. This is because, while a shell function is running, the positional parameters are temporarily replaced with the arguments to the function. This lets functions accept and use their own positional parameters.

How do you pass a single quote in a shell script?

You can use backslash(\) or double quotes(") to escape single quotes in bash shell script. Backslash escapes the character that immediately follows it. By using single quotes inside double quotes, you can escape it.


1 Answers

Inside single quotes everything is preserved literally, without exception.

That means you have to close the quotes, insert something, and then re-enter again.

'before'"$variable"'after' 'before'"'"'after' 'before'\''after' 

Word concatenation is simply done by juxtaposition. As you can verify, each of the above lines is a single word to the shell. Quotes (single or double quotes, depending on the situation) don't isolate words. They are only used to disable interpretation of various special characters, like whitespace, $, ;... For a good tutorial on quoting see Mark Reed's answer. Also relevant: Which characters need to be escaped in bash?

Do not concatenate strings interpreted by a shell

You should absolutely avoid building shell commands by concatenating variables. This is a bad idea similar to concatenation of SQL fragments (SQL injection!).

Usually it is possible to have placeholders in the command, and to supply the command together with variables so that the callee can receive them from the invocation arguments list.

For example, the following is very unsafe. DON'T DO THIS

script="echo \"Argument 1 is: $myvar\"" /bin/sh -c "$script" 

If the contents of $myvar is untrusted, here is an exploit:

myvar='foo"; echo "you were hacked' 

Instead of the above invocation, use positional arguments. The following invocation is better -- it's not exploitable:

script='echo "arg 1 is: $1"' /bin/sh -c "$script" -- "$myvar" 

Note the use of single ticks in the assignment to script, which means that it's taken literally, without variable expansion or any other form of interpretation.

like image 90
Jo So Avatar answered Oct 05 '22 01:10

Jo So