Expansion of variable inside single quotes in a co

2018-12-31 06:11发布

I want to run a command from a bash shell 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.

7条回答
栀子花@的思念
2楼-- · 2018-12-31 06:42

just use printf

instead of

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

use printf to replace the variable token with the expanded variable.

For example:

template='.... %s'

repo forall -c $(printf "${template}" "${variable}")
查看更多
千与千寻千般痛.
3楼-- · 2018-12-31 06:50

Does this work for you?

eval repo forall -c '....$variable'
查看更多
流年柔荑漫光年
4楼-- · 2018-12-31 06:56

Below is what worked for me -

QUOTE="'"
hive -e "alter table TBL_NAME set location $QUOTE$TBL_HDFS_DIR_PATH$QUOTE"
查看更多
孤独寂梦人
5楼-- · 2018-12-31 06:58

Variables can contain single quotes.

myvar=\'....$variable\'

repo forall -c $myvar
查看更多
像晚风撩人
6楼-- · 2018-12-31 07:01

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'

As you can verify, each of the above lines is a single word to the shell. String concatenation is simply done by juxtaposition. Quotes (single or double quotes, depending on the situation) are 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.

查看更多
情到深处是孤独
7楼-- · 2018-12-31 07:06

EDIT: (As per the comments in question:)

I've been looking into this since then. I was lucky enough that I had repo laying around. Still it's not clear to me whether you need to enclose your commands between single quotes by force. I looked into the repo syntax and I don't think you need to. You could used double quotes around your command, and then use whatever single and double quotes you need inside provided you escape double ones.

查看更多
登录 后发表回答