Linux / Bash: how to unquote?

Next command

echo 'ab' 'c' 

exits

 abc 

But the following

 X="'ab' 'c'" echo $X; 

will outout

 'ab' 'c' 

I am looking for a way to unquote $ X, so that it prints "abc" but does not lose the combined argument "a". (= 2 arguments instead of 3, does not matter for the 'echo' command, but for other commands, such as 'cp')

+6
source share
8 answers

Try xargs:

 $ echo $x 'ab' 'c' $ echo $x | xargs ./echo argc = 3 argv[0] = ./echo argv[1] = ab argv[2] = c 
+7
source
 eval echo $x 

this will pass ab as the first argument and c as the second

Note: this will actually evaluate the arguments, for example:

 $ x='$((3+5))' $ eval echo $x 8 

If this is not what you want to use @vanza xargs.

+7
source

Usually, if you are trying to save several "words" in one variable, it is recommended to use not built-in quotation marks, but use an array:

 X=('ab' 'c') printf "%s\n" "${X[@]}" 

prints:

 ab c 
+1
source

This is hairy, I would recommend getting around the problem and not concatenating "a" and "c" in the first place.

0
source
 X="'ab' 'c'" echo $X eval "echo $X" 

When using this code, you should be careful if X can contain special characters, such as \"$ or backlinks.

0
source

Are you sure echo gets 2 parameters in echo $X ? For me, he gets 3. Let's try:

 X="'ab' 'c'" function f(){ echo $#; echo $1; echo $2; echo $3; } f $X 

displayed:

 3 'a b' 'c' 

3 parameters: 'a , b' and 'c' . I do not think this is what you expect.

If you want to create a multi-parameter variable, set IFS to char, which you will not use (possibly | ), and use it as a parameter separator in your variable:

 X="ab|c" IFS="|" function f(){ echo $#; echo $1; echo $2; } f $X 
0
source

You can also combine xargs and sh -c 'cmd' _ arg1 arg2 ... to repeat the arguments into an array of positional parameters $@ .

Assigning output to a variable and redirecting anything other than exit state $? The last process on stderr , for example, allows you to save the completion code of the last process in a variable and use it after xargs completed execution.

 X="'ab' 'c'" ret="$( export IFS='' set -o pipefail echo $X | xargs sh -c ' for file in " $@ "; do echo cp "$file" destdir 1>&2 || { echo $?; kill -HUP $PPID; exit $?; } #(exit 3) || { echo $?; kill -HUP $PPID; exit $?; } #(exit 3) || { echo $?; kill -HUP $PPID; kill -HUP -- -$$; } done echo $? ' _ echo $? '|' ${PIPESTATUS[@]} 1>&2 )" echo "$ret" | tail -1 
0
source

Please do not use eval for something like this. set preserve the integrity of parameters and commands other than echo , will work well with them. Just keep in mind that you will lose the link to any current positional parameters.

 set -- "ab" "c" echo " $@ " #abc echo $1 #ab echo $2 #c 
0
source

Source: https://habr.com/ru/post/894583/


All Articles