Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Advertise on LowEndTalk.com
Bash Script Variable Question
New on LowEndTalk? Please Register and read our Community Rules.

Bash Script Variable Question

I have this bash script that isn't working the way I want it. In my script, I first create a variable called 'ip' which is the ip address for the server using this command:

ip=`grep IPADDR /etc/sysconfig/network-scripts/ifcfg-venet0:0 | awk -F= '{print $2}'`
echo $ip

The followup echo indeed shows my correct ip address. The next lines of code are used to create my openvpn.conf file:

#create the server config file
ovpnsettings='
dev tun
server 10.10.10.0 255.255.255.0
port 443
ifconfig-pool-persist ipp.txt
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
push "route 10.10.10.0 255.255.255.0"
push "redirect-gateway"
push "dhcp-option DNS 8.8.8.8"
float
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
group nobody
crl-verify crl.pem
verb 4
log /var/openvpn.log
status openvpn-status.log
management $ip 5555
daemon'

echo "$ovpnsettings" > /etc/openvpn/openvpn.conf

Yet when I look at that file after it is written, the line near the bottom says:

management $ip 5555 and not management 192.168.1.1 5555 like I would expect it to. A subsequent echo $ip after this still shows the correct ip address being retained by the variable.

Any ideas of why this isn't working as expected?

Thanks

Sarcasm: Just one more service I offer

Comments

  • alexhalexh Member
    edited October 2014

    Your variable is inside single quotes at the bottom. Remove it from single quotes and it will echo correctly.

  • You'd need to use double quotes for ovpnsettings, to have $ip expanded to its value.

  • Bash variable substitution doesn't happen within single quotes, e.g.

    ovpnsettings=' $ip '

    Use double quotes instead, then change the inside double quotes to single ones, e.g.,

    push 'redirect-gateway'

    or if that creates an issue, try escaping them:

    push \"redirect-gateway\"

  • Sure enough, the single quotes is the issue....learn something new every day.

    Thanks all!

    Sarcasm: Just one more service I offer

  • Generally the following applies for bash:

    DO use quotes for all text

    # THIS IS BAD
    foo=bar
    
    # THIS IS BETTER
    foo="bar"
    

    DO use double quotes for variable expansion

    foo="1"
    bar="$foo"
    echo $bar # 1
    

    DO use single quotes by default

    You should generally always use single quotes unless you explicitly want variable expansion. This will help prevent accidental expansion where you don't want it, and allows you to post most characters without having to escape them (such as double quotes, dollar signs, etc.)

    DO NOT use backticks for execution

    This is the old way of doing things.

    DO use dollar brackets for execution

    This is the new way of doing things.

    # THIS IS BAD
    output=`uptime`
    
    # THIS IS BETTER
    output=$(uptime)
    

    Then you don't have to worry about variable expansion, and a lot of other fun things. Consider the following as an example as to why you might want to use the new dollar bracket style of execution:

    echo "Active Sessions (for your user, by IP):"
    echo $(w | grep "$(whoami)" | awk '{print $3}' | sort)
    

    Not here that the quoting is not necessary, but is advised. While a username should never contain a space in a sane *nix system, it is possible, and the extra quotes will not otherwise harm program execution. Notice here how we did not need to take any special care to escape anything to make it "just work".

    Notice as well that single quotes must be used for the awk line, to prevent $0 to be expanded into the actual variable $0. Alternatively, you could escape the dollar sign; but this would cause more trouble than is required (and is error prone.)

    Thanked by 2jar ehab

    Acting Director of Albino Geek Services Ltd. My Keybase ID ( gh )
    GoodHosting.co | Enterprise KVM Virtual Private Servers | Twitter / Status : @ GoodHostingCo

  • geodirkgeodirk Member
    edited October 2014

    GoodHosting said: DO NOT use backticks for execution This is the old way of doing things. DO use dollar brackets for execution This is the new way of doing things.

    Fantastic advice! Thanks! Based on this, I modified my initial line to go from:

    ip=grep IPADDR /etc/sysconfig/network-scripts/ifcfg-venet0:0 | awk -F= '{print $2}'

    to:

    ip=$(grep IPADDR /etc/sysconfig/network-scripts/ifcfg-venet0:0 | awk -F= '{print $2}')

    Now I've learned TWO things in one day!!

    Sarcasm: Just one more service I offer

  • raindog308raindog308 Administrator, Moderator

    GoodHosting said: DO NOT use backticks for execution

    This is the old way of doing things.

    DO use dollar brackets for execution

    This is the new way of doing things.

    What exactly do you mean by "new"? If you mean "compared to 1970s Bourne shell" then yes, you are right. But the dollar brackets were in POSIX.2 which is 1992. So "new" means 20+ years :-)

    http://mywiki.wooledge.org/BashFAQ/082

    A nice site that has a lot of bash stuff:

    http://wiki.bash-hackers.org/doku.php

    Thanked by 1vRozenSch00n

    For LET support, please visit the support desk.

  • @raindog308 said:

    Of course, but people are still using the old way :).

    Acting Director of Albino Geek Services Ltd. My Keybase ID ( gh )
    GoodHosting.co | Enterprise KVM Virtual Private Servers | Twitter / Status : @ GoodHostingCo

Sign In or Register to comment.