Setting a variable in bash -c

I am trying to set a variable that gets the ip-address interface from ifconfig and reads it later. But when I execute the echo command, the variable is still empty. Check out my code:

 /usr/bin/bash -c "HOST_IPS=$(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet / && cnt==1) {print $2} cnt++}'); echo $HOST_IPS" 

But / bin / echo works with the same command:

 /usr/bin/bash -c "echo $(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet / && cnt==1) {print $2} cnt++}')" 
+6
source share
3 answers

You need to exit the $ sign in the final echo command, or the $HOST_IPS variable will be replaced on the command line before the subshell is issued:

 /usr/bin/bash -c "HOST_IPS=$(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet / && cnt==1) {print $2} cnt++}'); echo \$HOST_IPS" 

For more immediate visibility:

 # v-- insert backslash here /usr/bin/bash -c "HOST_IPS=$(same as before); echo \$HOST_IPS" 

Unlike @gniourf_gniourf's comment, there really is no need to avoid other dollar signs. However, as written, substitution substitution is not performed by a subshell (!); its result is replaced by the command line, which is passed to the subshell. Challenges

 mypid() { echo $$; } bash -c "pid=$(mypid); echo \$pid; mypid" 

demonstrate how it works: it once prints the PID of the parent shell and once complains that mypid not a known command because the subshell does not know this function.

Since running the ifconfig | awk ifconfig | awk in the parent shell is unlikely to be a problem; you can probably leave the replacement part of the commands unchanged. If it is important that the command is run by a subshell, you will also have to avoid all things.

+6
source

With /usr/bin/bash you start a subshell. When the shell is completed, all settings in the shell will be lost.
The following subset is set in the subshell and is lost before the echo is displayed:

 /usr/bin/bash -c sub=1; echo $sub 

You want to set a variable in a subshell, use stdout to transfer the value:

 sub=$(/usr/bin/bash -c "echo 1"); echo $sub 
0
source

From your question and example, your task does not require you to leave your current environment, so you do not need to start a new one and be associated with lost data.

 HOST_IPS=(); while read -r; do [[ $REPLY =~ "inet "([^/]*) ]] && HOST_IPS+=(${BASH_REMATCH[1]}); done < <( ip -f inet address show ) 

If you want to keep a list of the interface IP addresses, you can handle the ip output (or ifconfig ) in the current shell without calling awk .

0
source

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


All Articles