Hi guys,
I have a small script which reads my IP address from an URL and then sets it :
#!/bin/bash
MAC_ADDR=$(ifconfig eth0 | sed -n 's/.*HWaddr \([a-f0-9:]*\).*/\1/p')
IP=($(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDR/local-ipv4s))
for ip in ${IP[@]:1}; do
echo "Adding IP: $ip"
ip addr add dev eth0 $ip/24
done
I saved it in a file script.sh with exec rights. Now I am trying to put it under /etc/rc.local to run at startup.
My rc.local looks like :
root@ip-10-0-0-184:~# cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
sh /root/script.sh
exit 0
When I run it via ./script.sh all works fine. When I try to run it via sh I get the following
/root/script.sh: 3: /root/script.sh: Syntax error: "(" unexpected
Do you have any insights on how can I fix that ?
That error comes from using a bourne shell - are you on Solaris, or more correctly what shell does /bin/sh invoke?
Please show the output of:
ls -l /bin/sh
uname -a
lrwxrwxrwx 1 root root 4 Mar 29 2012 /bin/sh -> dash
Linux ip-10-37-161-45 3.2.0-40-virtual #64-Ubuntu SMP Mon Mar 25 21:42:18 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
FWIW - https://bugs.launchpad.net/ubuntu/\+source/dash/\+bug/141481
dash is supposed to be POSIX-compliant but it still seems that it does not have all of the features that bash has, the $( ) construct is an example. You need to use backticks
Example:
`my command`
# instead of
$( my command)
PS: I don't use dash, but you should be aware of the gotchas if you choose to keep using it. dash is not meant as a one-to-one replacement for bash.
1 Like
Thanks, it was really helpful.
I guess cd /root && ./script.sh will also right straight from rc.local ...right ?
According to its documentation, dash does support the modern, POSIX-compliant $(...) command substitution syntax.
I don't use dash either, but I suspect the problem lies with the parentheses surrounding the command substitution, which look like a bash list/array assignment.
Regards,
Alister
What would be the fastest way to sort this out ?
Tried actually the following :
#!/bin/bash MAC_ADDR=`ifconfig eth0 | sed -n 's/.*HWaddr \([a-f0-9:]*\).*/\1/p'` IP=`(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDR/local-ipv4s)` for ip in ${IP[@]:1}; do echo "Adding IP: $ip" ip addr add dev eth0 $ip/24 done
But still getting an error..
If it works with bash, then just use bash.
The errors are the result of running a script which depends on arrays and array operations on a shell which does not support arrays. dash aims to be a nimble shell which does not support much beyond the POSIX standard. sh arrays are not part of POSIX.
If you need to port it to sh/dash, then you must abandon the arrays and utilize a different approach, e.g. pipe curl's output into a while-loop.
Also, please, don't be vague when reporting errors. Instead of "still getting an error", post the exact error message.
Regards,
Alister
Try replacing
IP=($(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDR/local-ipv4s))
with
IP=$(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDR/local-ipv4s)