0

I have a shell script which reads a file in to an array. It works perfectly with RHEL, but when i run the same script on Ubuntu i am getting an error. Here is the script.

file=/root/monitor.txt
while IFS=',' read -ra line ; do
        echo -e "export MASTER_IP=${line[2]}" >> ~/.bashrc
        source ~/.bashrc
done < $file

The above script works perfectly in RHEL. The error i am getting when i run it on Ubuntu is

read: Illegal option -a
2
  • 2
    The -a option is just for bash. Check this page Unix - Using Shell Arrays for reference. Commented Sep 2, 2014 at 8:25
  • For pure POSIX sh, arrays don't exist -- they're a ksh feature adopted by bash, zsh, etc. Fortunately, you don't need them. Commented Sep 3, 2014 at 12:06

2 Answers 2

5

read -a is a bash feature, but on Ubuntu /bin/sh points to dash, which doesn't support the -a option. There are a few ways you could solve this problem:

  • On Ubuntu, just run the script under bash, by changing the first line to #!/bin/bash (as suggested by Charles Duffy)

  • Instead of read -a, just give a list of variables, such as read f1 f2 f3 f4 f5 and then refer to the fields as $f1, $f2 etc. In this case, if you have more than 5 fields, you need to add more variables, otherwise $f5 will contain the rest of the line.

  • Use awk instead of read. Awk is a good fit for this kind of field-processing task: you could replace the while loop with something like awk -F, '{print "export MASTER_IP=" $3}' $file >> ~/.bashrc, and then source ~/.bashrc at the end.

Sign up to request clarification or add additional context in comments.

2 Comments

I'd at least directly mention changing the shebang as an option.
I didn't think of that, that's a much nicer solution. I've edited it in. Thanks!
3
while IFS=, read -r _ _ ip _; do
  printf 'export MASTER_IP=%s\n' "$ip"
done <"$file" >>"$HOME/.bashrc"

This is better in a few respects:

  • Doesn't require any bashisms; will work with /bin/sh on Ubuntu.
  • Opens the output file only once for the whole loop, instead of inefficiently reopening it every time a new line is to be written.

However, you can do better -- improving your script's security -- if you change its shebang to be #!/bin/bash (or /usr/bin/env bash, or otherwise as appropriate for your platform):

#!/bin/bash
while IFS=, read -r _ _ ip _; do
  printf 'export MASTER_IP=%q\n' "$ip"
done <"$file" >>"$HOME/.bashrc"

Because this uses %q instead of %s, it also escapes the addresses, so they can't contain malicious content like $(rm -rf $HOME) -- something you probably don't want injected into your ~/.bashrc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.